En Kotlin, si no desea inicializar una propiedad de clase dentro del constructor o en la parte superior del cuerpo de la clase, tiene básicamente estas dos opciones (de la referencia del lenguaje):
lazy () es una función que toma un lambda y devuelve una instancia de Lazy que puede servir como delegado para implementar una propiedad lazy: la primera llamada a get () ejecuta el lambda pasado a lazy () y recuerda el resultado, llamadas posteriores para obtener () simplemente devuelve el resultado recordado.
Ejemplo
public class Hello { val myLazyString: String by lazy { "Hello" } }
Entonces, la primera llamada y las llamadas secundarias, donde sea que esté, a myLazyString devolverán "Hola"
Normalmente, las propiedades declaradas como de tipo no nulo deben inicializarse en el constructor. Sin embargo, con bastante frecuencia esto no es conveniente. Por ejemplo, las propiedades se pueden inicializar mediante la inyección de dependencia o en el método de configuración de una prueba unitaria. En este caso, no puede proporcionar un inicializador no nulo en el constructor, pero aún así desea evitar verificaciones nulas al hacer referencia a la propiedad dentro del cuerpo de una clase.
Para manejar este caso, puede marcar la propiedad con el modificador lateinit:
public class MyTest { lateinit var subject: TestSubject @SetUp fun setup() { subject = TestSubject() } @Test fun test() { subject.method() } }
El modificador solo se puede usar en propiedades var declaradas dentro del cuerpo de una clase (no en el constructor primario), y solo cuando la propiedad no tiene un captador o definidor personalizado. El tipo de la propiedad debe ser no nulo y no debe ser un tipo primitivo.
Entonces, ¿cómo elegir correctamente entre estas dos opciones, ya que ambas pueden resolver el mismo problema?
lateinit
expone su campo de respaldo con visibilidad del configurador, por lo que las formas en que se accede a la propiedad desde Kotlin y desde Java son diferentes. Y desde el código Java, esta propiedad se puede configurar inclusonull
sin ninguna comprobación en Kotlin. Porlateinit
lo tanto, no es para la inicialización diferida, sino para la inicialización no necesariamente del código de Kotlin.