Tips:在AndroidStudio的Java文件中编写一段代码,然后将其粘贴到kt文件中,它会自动转换为Kotlin
基本数据类型
Kotlin 的基本数值类型包括 Byte、Short、Int、Long、Float、Double 等。不同于Java的是,字符不属于数值类型,是一个独立的数据类型。
类修饰符
// 属性修饰符
annotation //注解类
abstract //抽象类
final //类不可继承,默认属性
enum //枚举类
open //类可继承,类默认是final的
// 访问权限修饰符
private //仅在同一个文件中可见
protected //同一个文件中或子类可见
public //所有调用的地方都可见
internal //同一个模块中可见
//注:新建的类默认是final的,想要被继承需要加open修饰符
类的构造器
class Person(name : String, age : int) {
}
翻译成java为:
final public class Person {
public Person(String name, int age){
}
}
//kotlin默认生成一个带参的构造函数,kotlin中的类定义同时也是构造函数,kotlin增加了一个新的关键字init用来处理类的初始化问题,init模块中的内容可以直接使用构造函数的参数
class Person(name : String, age : int){
init{
// to do something
}
}
//kotlin中如何实现不同参数的构造函数
//提供了次级构造函数,次级构造函数用constructor加上参数,后面用this加上主构造函数的参数。同时次级构造函数中可以直接进行代码操作
class CustomView :TextView{
constructor(context: Context?) : this(context,null)
constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs,0)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
}
Android 中的使用
View的操作
var textview:TextView? = null
textview = findViewById(R.id.tv) as TextView
textview.setOnClickListener{
toast("Hello world!")
}
// 注:
// ?:表示当前是否对象可以为空
// !!: 表示当前对象不为空的情况下执行,为空则抛出空指针异常
接口中的回调写法
weather.enqueue(object :Callback{
override fun onFailure(call: Call?, t: Throwable?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onResponse(call: Call?, response: Response?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
})
mBack.setOnClickListener(
object : View.OnClickListener {
override fun onClick(v: View) {
finish()
}
})
静态方法
//伴生对象的初始化是在类加载的时候,与java的静态初始化器相对应
companion object{
//这里写方法
}
//注:一个类只能有一个伴生对象
单例写法
//类似java的静态内部类实现单例模式
class WeatherManager private constructor(){
companion object {
fun get():WeatherManager{
return Holder.instance
}
}
private object Holder{
val instance = WeatherManager()
}
}
接口定义
interface MyInterface {
fun bar() // 未实现
}
继承和实现
class Man : Person(){
}
扩展函数
//我们可以在不改变源码的情况下,为源码新增一个我们需要的方法
// 扩展函数 swap,调换不同位置的值
fun MutableList.swap(index1: Int, index2: Int) {
val tmp = this[index1] // this 对应该列表
this[index1] = this[index2]
this[index2] = tmp
}
fun main(args: Array) {
val l = mutableListOf(1, 2, 3)
// 位置 0 和 2 的值做了互换
l.swap(0, 2) // 'swap()' 函数内的 'this' 将指向 'l' 的值
println(l.toString())
}
when 表达式
//kotlin中没有switch case表达式,但是提供了一个when表达式
//switch-case
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case FeedbackInfoLogic.MSG_FEEDBACK_INFO_REQUEST_SUCCESS:
break;
case FeedbackInfoLogic.MSG_FEEDBACK_INFO_REQUEST_FAILED:
break;
case FeedbackInfoLogic.MSG_FEEDBACK_INFO_REQUEST_SUCCESS_EMPTY:
break;
default:
break;
}
return super.handleMessage(msg);
}
//when
fun handleMessage(msg: Message): Boolean {
when (msg.what) {
FeedbackInfoLogic.MSG_FEEDBACK_INFO_REQUEST_SUCCESS -> {
}
FeedbackInfoLogic.MSG_FEEDBACK_INFO_REQUEST_FAILED -> {
}
FeedbackInfoLogic.MSG_FEEDBACK_INFO_REQUEST_SUCCESS_EMPTY -> {
}
else -> {
}
}
return super.handleMessage(msg)
}
//else相当于default
POJO类
//传统的java POJO类会要求写一系列的模板代码
public class User{
private long id;
private String name;
private String url;
private String mbid;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getMbid() {
return mbid;
}
public void setMbid(String mbid) {
this.mbid = mbid;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", url='" + url + '\'' +
", mbid='" + mbid + '\'' +
'}';
}
}
//而在kotlin中可以这样写
//使用关键字data会自动生成相应的 equals、hashcode、toString 方法
data class User(
var id: Long,
var name: String,
var url: String,
var mbid: String)
//或
class User{
var id:Long? = null
var name:String? = null
var url:String? = null
var mbid:String? = null
}
Elvis操作符
// 使用Elvis操作符来给定一个在是null的情况下的替代值,当user为null时name = empty
val name = user?.name ?: "empty"
let操作符
// let 操作符:如果对象的值不为空,则允许执行这个方法。
//Java
if (user != null) {
text.setText(currentUser.name)
}
//Kotlin
user?.let {
println(it.name)
}
//it代表user这个对象
with 函数
//with 是一个非常有用的函数,它包含在 Kotlin 的标准库中。它接收一个对象和一个扩展函数作为它的参数,然后使这个对象扩展这个函数。这表示所有我们在括号中编写的代码都是作为对象(第一个参数) 的一个扩展函数,我们可以就像作为 this 一样使用所有它的 public 方法和属性。当我们针对同一个对象做很多操作的时候这个非常有利于简化代码。
with(helloWorldTextView) {
text = "Hello World!"
visibility = View.VISIBLE
}
常用集合
List
A generic ordered collection of elements. Methods in this interface support only read-only access to the list
(一个有序的集合,仅支持对list的读,不支持写)
MutableList
A generic ordered collection of elements that supports adding and removing elements.(支持添加和移除元素的有序集合)
Set
A generic unordered collection of elements that does not support duplicate elements.
Methods in this interface support only read-only access to the set;(不支持修改的无序的、不允许有重复元素的集合)
MutableSet
A generic unordered collection of elements that does not support duplicate elements, and supports
adding and removing elements.(支持添加和移除元素的无序的、不允许有重复元素的集合)
字符串相关
模板字符串
//使用$符号,避免字符串的拼接
val a = "android"
val name = "$a length is ${a.length}"
//name = android lenght is 7
原始字符串
//使用""" """包围的字符串会保留原格式
val str = """
|java
|kotlin
|scala
|python
"""
列表遍历
//可以使用如下代码使用下标来遍历数组
for(i in list.indices){
println(list[i])
}
//使用迭代器遍历
val iterator = list.iterator()
while (iterator.hasNext()){
println(iterator.next())
}
//使用forEach遍历,算是kotlin中的一个语法糖
list.forEach {
println(it)
}
Kotlin内存优化
//使用懒加载,懒加载更有效率的利用内存,因为我们只需要调用资源才能将资源加载到内存中
val weatherService: WeatherService by lazy {
val retrofit: Retrofit = Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(MoshiConverterFactory.create())
.build()
retrofit.create(WeatherService::class.java)
}
//在调用weatherService的情况下才初始化weatherService,可以优化内存
面向对象
object类
//实现类似java中工具类可以使用object
object FileUtils {
fun getFiles(){
println("this is files")
}
}
//调用方法
FileUtils.getFiles()
一些学习网站
From Java to Kotlin:列出了许多 Java 与 Kotlin 对比的例子
Kotlin 在线练习题,适合有一定基础的 Kotlin 学习者
16 Kotlin Tips for Android Development