我最近查看了一些kotlin代码,所有可为null的字段都初始化为null。
val x : String? = null
和val x : String?
有什么区别
我们应该将可为null的字段初始化为null吗?
所有东西,甚至是可为null的变量和基元,都需要在Kotlin中初始化。正如tynn所提到的,如果需要重写,可以将它们标记为抽象。但是,如果您有一个接口,则不必初始化它们。这不会编译:
class Whatever {
private var x: String?
}
但这将:
interface IWhatever {
protected var x: String?
}
这也是:
abstract class Whatever {
protected abstract var x: String?
}
如果它是在方法中声明的,那么您不必直接初始化它,只要它在被访问之前被初始化即可。如果你熟悉的话,这和Java中的完全一样
如果没有在构造函数中初始化它,则需要使用lateinit
。或者,如果您有val
,您可以覆盖get
:
val something: String?
get() = "Some fallback. This doesn't need initialization because the getter is overridden, but if you use a different field here, you naturally need to initialize that"
正如我用打开的那样,即使是可以为null的变量也需要初始化。这就是Kotlin的设计方式,没有办法绕过它。因此,是的,如果不立即用其他方法初始化String,则需要将其显式初始化为null。
var x : String? = null
。不赋值只是属性的声明,因此必须使其抽象为abstract val x : String?
。
或者,也可以在不可为null的类型上使用lateinit
。但这样做的效果是,它不是null,而是未初始化的lateinit var x : String
。
val x : String?
将创建一个未初始化的变量或属性,具体取决于它的定义位置。如果它在一个类(而不是一个函数(中,它会创建一个属性,除非它是抽象的,否则不能创建未初始化的属性。例如,以以下代码为例:
class MyClass {
val x : String?
}
这不会编译。你会得到Property must be initialized or be abstract
。
然而,此代码将编译
class MyClass {
fun test() {
val x : String?
}
}
然而,这有点毫无意义,因为您将无法引用该变量:一旦引用,您将获得Variable 'x' must be initialized.
因此,是的,通常在定义一个可为null的成员时,你应该初始化它(例如,使用null值(,除非它是抽象的,在这种情况下,重写类应该初始化它