1、安全调用运算符: “?.”
它允许你把一次null检查和一次方法调用合并成一个操作。
如:
s?.toUpperCase()等效于:
if(s != null) s.toUpperCase()
else null2、Elvis运算符: “?:”
Elvis运算符(或者null合并运算符)
Elvis运算符接收两个运算数,如果第一个运算数不为null,运算结果就是抵押给运算数;否则,运算结果就是第二个运算数。
foo ?= bar变换如下:
foo != null -> foo
foo == null -> bar
3、安全转换:"as?"
用于数据类型的常规Kotlin运算符:as运算符。
as?运算符尝试把值转换为指定的类型,如果值不是合适的类型就返回null,如下
foo as? Type变换如下:
foo is Type -> foo as Type
foo !is Type -> null
4、非空断言:"!!"
非空断言是Kotlin提供给你的最简单直率的处理可空类型值的工具。
它使用双感叹号表示,可以把任何值转换成非空类型。
如果对null值做非空断言,则会抛出异常。
foo!!转换如下
foo != null -> foo
foo == null -> NullPointerException注意:使用"!!"并且它的结果是异常时,异常调用栈的跟踪信息值表明异常发生在哪一行代码,而不会表明异常发生在哪一个表达式。为了让跟踪信息更清晰精确地表示哪个值为null,最好避免在同一行中使用多个"!!"断言
5、"let"函数
let函数让处理可空表达式变得更容易。
和安全调用运算符一起,它允许你对表达式求值,检查求值结果是否为null,并把结果保存为一个变量。
foo?.let {
...it...
}
转换如下:
foo != null 在lambda内部it是非空的
foo == null 什么都不会发生
6、延迟初始化的属性
使用lateinit修饰符来完成这样的声明:
如下:
class MyService{
fun performAction(): String = "foo"
}
class MyTest{
private lateinit var myService: MyService
fun setUp(){
myService = MyService()
}
fun testAction(){
Objects.equals("foo",
myService.performAction())
}
}注意:延迟初始化的属性都是var,因为需要在构造方法外修改它的值,而val属性会被编译成必须在构造方法中初始化的final字段。
注意:lateinit属性常见的一种用法是依赖注入。在这种情况下,lateinit属性的值是被依赖注入框架从外部设置的。
7、可空类性的扩展
Kotlin标准库中定义的String的两个扩展函数isEmpty和isBlank就是这样的例子。
第一个函数判断字符串是否是一个空的字符串“”;
第二个则判断它是否是空或者它只包含空白字符。
因而就有isEmptyOrNull和isNullOrBlank就可以由String?类型的接受者调用。
8、data class作用
在Kotlin中,无需手写一个JavaBean,可以直接使用data class,使用data class后编译器会自动生成如下方法
equals()
hashCode()
toString()
componentN()
copy()注意数据类的前提条件:
- 主构造方法至少要有一个参数
- 所有的主构造方法参数都需要被标记为var或val
- 数据类不能是抽象类、open类、sealed类(密封类)、inner类
数据类的定义示例:
data class Person(val name: String, var age: Int, var address: String)数据类的使用:
fun main(){
var person = Person("yang", 26, "hubei")
println(person)
}方法说明:
- copy()
copy():作用在赋值时,很方便
在Java中,一个对象的类成员如果被另一个对象复制,仅仅修改了一个参数,那么需要把这个对象的所有值都赋值给另外一个对象,这样非常麻烦
在kotlin中,可以通过copy()方法执行修改某个参数
注意:如果不加参数名字,那么默认是第一个,否则必须明确参数名
图片来源:kotlin语言学习11 ——kotlin的data class(数据类)
- 2. componentN()
componentN的方法主要在于,解构声明:
- 解构:在主构造方法中有多少个参数就会生成多少个component方法
- 这些方法返回对应字段的值,component方法时用来实现解构声明的
补充
什么是解构声明?
在kotlin中可以把一个对象复制给多个变量,这种操作叫做解构声明(Destructuring declaration)。
先看如下例子:
data class Book(var name: String, var price: Float)
fun main(args: Array<String>) {
val (name, price) = Book("Kotlin入门", 66.6f)
println(name)
println(price)
}
// 输出
Kotlin入门
66.6
我们定义了一个简单的数据类(data class),name、price变量分别输出了对应的属性值,大大简化了我们的操作!
数据类之所以可以使用解构声明,是由于数据类比较特殊,编译器默认为它声明了类似的函数:
operator fun component1(): String {
return name
}
operator fun component2(): Float {
return price
}
为name、price变量赋值相当于分别调用了Book对象的component1()、component2()函数,也就是解构的核心原理。