In Kotlin, if you don't want to initialize a class property inside the constructor or in the top of the class body, you have basically these two options (from the language reference):
- Lazy Initialization
lazy()
is a function that takes a lambda and returns an instance of Lazy<T>
which can serve as a delegate for implementing a lazy property: the first call to get()
executes the lambda passed to lazy()
and remembers the result, subsequent calls to get()
simply return the remembered result.
Example
public class Hello {
val myLazyString: String by lazy { "Hello" }
}
So, the first call and the subsequential calls, wherever it is, to myLazyString
will return Hello
- Late Initialization
Normally, properties declared as having a non-null type must be initialized in the constructor. However, fairly often this is not convenient. For example, properties can be initialized through dependency injection, or in the setup method of a unit test. In this case, you cannot supply a non-null initializer in the constructor, but you still want to avoid null checks when referencing the property inside the body of a class.
To handle this case, you can mark the property with the lateinit modifier:
public class MyTest {
lateinit var subject: TestSubject
@SetUp fun setup() { subject = TestSubject() }
@Test fun test() { subject.method() }
}
The modifier can only be used on var properties declared inside the body of a class (not in the primary constructor), and only when the property does not have a custom getter or setter. The type of the property must be non-null, and it must not be a primitive type.
So, how to choose correctly between these two options, since both of them can solve the same problem?
Question&Answers:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…