Kotlinlateinit 修饰符是在你想声明一个不可归零的变量而不初始化其值时使用的。
要使用这个修饰符,你需要在变量名称前添加它,如下所示:
lateinit var message: String
用lateinit 声明的变量必须使用var 关键字,而不是val 。这是因为你以后需要对变量的值进行变异。
当你用Kotlin声明一个不可归零的变量时,你需要在初始化时立即设置该值。
例如,如果你要定义一个String 变量,那么需要在声明时赋值,如下所示:
var myString: String = "Hello"
但是在开发应用程序时,会有这样的情况:你想声明的变量没有初始值。
这可能是该变量是一个类的成员,由一个函数初始化,由另一个函数调用。
考虑一下下面这个Message 类:
class Message {
lateinit var message: String
fun setMessage(message: String) {
this.message = message
}
fun getLength(): Int {
return message.length
}
}
正如你所看到的,Message 类的message 属性被初始化,没有任何值。
当setMessage() 函数被调用时,该值被设置。
当你先调用getLength() 函数时,Kotlin会抛出UninitializedPropertyAccessException 错误:
val msg = Message()
msg.getLength() // UninitializedPropertyAccessException
msg.newMessage("Hello!")
为了防止lateinit 变量出现任何错误,你需要在访问该变量之前检查该变量是否已经被初始化。
getLength() 方法需要使用.isInitialized 属性检查message 变量的初始化:
fun getLength(): Int {
return if(this::message.isInitialized) {
message.length
} else {
0
}
}
在Android应用程序中使用latinit修改器
当你创建一个有多个Activity 类的Android应用程序时,通常会使用该修改器。
类的变量值可能来自另一个类的Intent ,所以你需要在onCreate() 方法调用之前使用lateinit 来声明这些变量。
考虑一下下面的例子:
class PreviewActivity : AppCompatActivity() {
private lateinit var message: Message
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_preview)
message = intent.getSerializableExtra("Message") as Message
}
}
在上面的例子中,变量message 是一个Message 类的实例。
这个变量的值是由之前的Activity 类放在intent 上的额外数据初始化的。
如果不把这个变量定义为类成员,你就不能在onCreate() 方法之外使用message 这个变量。
你也可以将该变量定义为nullable类型,但这意味着你需要在初始化时将其值设置为null :
private var message: Message? = null
但之后每次你需要调用message 属性或方法时,你需要为非空断言的调用添加双击操作符!! :
message!!.contactName
message!!.getReplyAddress
有了lateinit 修改器,Kotlin不会抱怨你的变量的值,你也不需要在属性和方法的调用上添加双bang运算符。
现在你已经了解了lateinit 修改器在Kotlin中的作用。干得好!👍