在Kotlin中,如果您不想在构造函数内部或在类主体顶部初始化类属性,则基本上有以下两个选项(来自语言参考):
lazy()是一个函数,它需要一个lambda并返回Lazy的一个实例,该实例可以充当实现lazy属性的委托:对get()的第一次调用执行传递给lazy()的lambda并记住结果,随后的调用get()只是返回记忆的结果。
例
public class Hello { val myLazyString: String by lazy { "Hello" } }
因此,无论在哪里,对myLazyString的第一个调用和后续调用都将返回“ Hello”
通常,必须在构造函数中初始化声明为非空类型的属性。但是,这经常不方便。例如,可以通过依赖项注入或在单元测试的设置方法中初始化属性。在这种情况下,您不能在构造函数中提供非null的初始值设定项,但在引用类的主体内的属性时仍要避免执行null检查。
要处理这种情况,可以使用lateinit修饰符标记该属性:
public class MyTest { lateinit var subject: TestSubject @SetUp fun setup() { subject = TestSubject() } @Test fun test() { subject.method() } }
该修饰符只能用于在类主体内声明的var属性(不适用于主构造函数),并且只能在该属性没有自定义getter或setter的情况下使用。该属性的类型必须为非null,并且不能为原始类型。
那么,由于这两个选项都可以解决相同的问题,因此如何在这两个选项之间正确选择?
lateinit
它以设置者的可见性公开了它的支持字段,因此从Kotlin和Java访问属性的方式是不同的。从Java代码开始,甚至null
在Kotlin中无需检查也可以将此属性设置为。因此lateinit
,不是用于延迟初始化,而是用于不一定来自Kotlin代码的初始化。