Android项目中使用了一段时间的Kotlin,给我的体验还是不错的,上手比较容易,和Java完全兼容,相互调用也比较方便,代码量也减少了一部分,特此做一个小小的总结:
1. 万能的 :
2. 初始化和延时加载
3. Kotlin 变量、常量、类型推断
4. 空指针安全
5. 定义函数
6. 构造函数
7. 单例模式
8. 数据类
9. in、区间、集合
10. it、 let、 apply 、run、 with 函数
11. 补充
1. 万能的 :
作用 | 示例 |
---|---|
定义变量类型 | var hello:String = "Hello Kotlin" |
定义参数类型 | fun setName (name:String){ } |
定义函数返回值 | fun getName (name:String):String{} |
类的继承、实现 | class MainActivity : BaseActivity() , MyInterface {} 类的继承( 后面跟() )或实现都写在: 后面用, 隔开 |
调用 Java 类 | val intent = Intent(this, MainActivity::class.java) |
2. 初始化和延时加载
Kotlin中必须为变量赋值,否则会报错
val name //报错 val name = "Kotlin" //正确
有时候在定义变量的时候不能初始化,比如预定义控件不初始化
private val setTitle by lazy {
findViewById(R.id.tvTitle) as TextView
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setTitle.text= "Kotlin"
lazy
只适用 val
对象,对于 var
对象,使用 lateinit
lateinit var setName :String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setName = "Kotlin"
3. Kotlin 变量、常量、类型推断
val 定义常量 (相当于final) 创建时必须初始化,以后不能改变
val hello : String = "Hello Kotlin"
```kotlin
var 定义变量 和 Java 中声明的变量一样
```kotlin
var hello : String = "Hello Kotlin"
String
定义了数据类型,Kotlin
支持类型推断,可以省略
val hello = "Hello Kotlin"
var hello = "Hello Kotlin"
4. 空指针安全
用 ?
表示可以为空,用 !!
表示不可以为空
空指针安全并不是不需要处理空指针,而是用 ?
声明某个变量允许空指针
// 声明允许为空时,不能使用类型推断,必须声明数据类型
var name:String? = null
对于空指针的处理还要视情况而定
var name = name ? . toString() //不做处理返回 null
var name = name ? . toString() ? : "Kotlin" //判断为空时返回Kotlin
var name = name !! . toString() //抛出空指针
5. 定义函数
在 Kotlin 中,函数格式这样定义
fun 方法名(参数名:类型,参数名:类型...) :返回类型{
}
//例如
fun getAdd(a:Int, b:Int ):Int{
return a+b
}
因为 Kotlin 可以对函数的返回值进行类型推断,所以可以用 =
代替返回类型和return
//可以改写成这样
fun getAdd(a:Int, b:Int ):Int = {
a+b
}
//如果函数内代码只有一行,可以去掉 { }
fun getAdd(a:Int, b:Int ):Int = a+b
//如果函数允许空指针安全,在返回值后面加 ?
fun getAdd(a:Int, b:Int ):Int ?= a+b
6. 构造函数
-
Java 中,构造方法名和类名相同,而Kotlin 中,通过
constructor
关键字标明,分为主构造器 (Primary Constructor
) 和次级构造器 (Secondary Constructor
) -
primary constructor
在类的首部,关键字init
被称作初始化代码块,由于放在首部,不能包含任何初始化执行语句,那么可以把初始化执行语句放在init
中,class Person constructor(username: String, age: Int){ private val username: String private var age: Int init{ this.username = username this.age = age } }
-
当
constructor
关键字没有注解和可见性修饰符作用时可以省略 -
初始化执行语句也可以不放在
init
中,可以将构造器中的形参赋值给它//可以简写为 class Person(username: String, age: Int){ private val username: String = username private var age: Int = age
-
这样用构造器中的形参进行赋值,还可以简化为
class Person(private val username: String, private var age: Int){}
-
Secondary Constructor
定义在类中,可以有多个,Primary Constructor
只能有一个class MyButton : AppCompatButton { constructor(context: Context) : this(context, null) constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, R.attr.buttonStyle) constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) }
7. 单例模式
-
构造方法必须是
private
的,禁止手动创建对象 -
伴生对象
companion object
,它是该类所有实例共有的对象,类似Java
的静态字段public class SingleCase private constructor() { companion object { val instance: = SingleCase () } }
//带参数 class SingleCase private constructor(str: String) { var string: String = str; companion object { @Volatile var instance: SingleCase ? = null fun getInstance(c: String): SingleCase { if (instance == null) { synchronized(SingleCase ::class) { if (instance == null) { instance = SingleCase (c) } } } return instance!! } } }
8. 数据类
Java中定义数据Model时,要做的事情很多,getter/settet,equals(),ha shCode()等
但在Kotlin中,只需在class前添加data
修饰
data class User(var age:Int,var name:String)
9. in、区间、集合
示例 | 作用 |
---|---|
if (x in 1...5) {} | 检查x是否在1到5区间 |
if (item in list) {} | 检查list中是否有某个元素 |
for (x in 1...5){} | 遍历1到5 |
for(item in list) | 遍历list集合 |
for(item in 2...list-3) | 从第N项开始遍历 相当于 for(int i =3;i<=list.size()-3;i++){} |
for(item in list.size downTo 0){} | 倒序遍历 |
list.forEach{ } | Kotlin 集合自带函数 |
10. it、 let、 apply 、run、 with 函数
-
it
lambda 表达式可以把函数简写输入参数 ->(运算)输出
,如果是一个参数val dints=ints.map{value->value*2}
对于这种单个参数的运算可以把
参数声明
和->
都简化,只保留运输输出,这里就需要用it
来统一代替参数val dints2=ints.map{ it*2} //简化单参数的lambda表达式
-
let
把复杂的对象赋给itFile("a.text").let{ it.absoluteFile //let把file对象赋给了it }
这个特性可以扩展一下,增加
?
检查//检查返回值不是空才继续进行 getVaraiable()?.let{ it.length }
-
apply
可以操作一个对象的任意函数list.apply{ add("Hello") add(1,"Kotlin") }
-
run
apply
是操作一个对象,run
是操作一块代码
apply
返回操作的对象,run
返回最后一行代码的对象list.run(){ //操作一个集合 add(0,3) //操作该集合 var a=Activity() a //会返回最后一行的对象 }
-
with
with
像apply
也是操作一个对象,但它是把对象作为参数传入with
函数,返回像run
也是最后一行with(list){ add("Hello") var a = Activity() a //返回最后一行的对象 }
11. 补充
-
没有
;
Kotlin 中,代码结尾不需要写;
-
没有
new
实例化对象不需要new
var list = ArrayList()
-
is
取代instance of
if (str is String) { }
-
when
取代switch
-
字符串模版
"${para0}abc${para1}def"
-
Java 转 Kotlin:
Code ->Convert Java File to Kotlin
-
Kotlin 转 Java:
Tools ->Kotlin ->Show Kotlin Bytecode ->Decompile