En este tutorial hablaremos sobre las propiedades lateinit en Kotlin y cómo pueden proveerte un mecanismo para inicialización tardía
El Modificador lateinit
El modificador lateinit
te permite inicializar una propiedad no anulable por fuera del constructor.
Este mecanismo te ayuda cuando deseas asignar el valor de una propiedad después y no deseas usar comprobaciones de nulos (expresiones if, operador de acceso seguro o aserciones) una vez inicializada.
lateinit var propiedad:String
Restricciones De Propiedades lateinit
Ten en cuenta las siguientes restricciones a la hora de definir una propiedad lateinit
:
- Deben ser propiedades mutables
var
(es evidente, ya que necesitas cambiar el valor fuera del constructor) - Debe declararse en el cuerpo de la clase, no el constructor primario
- No deben tener accesores (get y set) personalizados
- No pueden declararse con tipos primitivos
- No pueden ser anulables
Ejemplo De Propiedades lateinit En Kotlin
Supongamos que hemos creado un pequeño framework para videojuegos compuesto de las clases Game
y VideoController
.
Game
representa a la entidad maestra que controla las reglas del mundo y la creación de las abstraciones como VideoController
.
Y VideoController
es el controlador asociado a la creación de escenas y renderizado.
Solución Con Propiedad Anulable
Proveeremos a Game
de dos métodos, init()
para inicializar el componente de video y createScene()
para generar la escena preliminar.
class VideoController(var screenWitdh: Int, var screenHeight: Int)
class Game {
private var videoController: VideoController? = null
fun init(witdh:Int, height:Int) {
videoController = VideoController(witdh, height)
}
fun createScene() {
print("Resolución de ${videoController?.screenWitdh}x" +
"${videoController?.screenHeight}")
}
}
Como no podemos dejar a videoController
sin valor hasta init()
, entonces lo declaramos como anulable para asignarle null
.
En createScene()
usaremos el operador de acceso seguro .?
para acceder a screenWitdh
y screenHeight
.
Como puedes notar, si en el futuro tuviésemos más usos del controlador de video dentro de Game
, tendríamos grandes cantidades de comprobaciones de nulos.
Resolvamoslo con el modificador lateinit
.
Solución Con Propiedad lateinit
Usa el modificador lateinit
en la declaración de videoController
.
private lateinit var videoController: VideoController
Inmediatemente IntelliJ IDEA te sugerirá que ya no es necesario el uso del operador ?.
:
Así que retiralos:
fun createScene() {
print("Resolución de ${videoController.screenWitdh}x" +
"${videoController.screenHeight}")
}
Ahora prueba su funcionamiento creando una instancia de Game
, inicializa los componentes y luego crea la escena:
fun main() {
val game = Game()
game.init(800,600)
game.createScene()
}
En la salida tendrás:
Resolución de 800x600
Comprobar Inicialización Con isInitialized
Si intentas comentar la línea game.init(800,600)
de la ejecución anterior, obtendrás una excepción del tipo UninitializedPropertyAccessException
:
Exception in thread "main" kotlin.UninitializedPropertyAccessException:
lateinit property videoController has not been initialized
Y es algo que se esperaba, el valor no tiene un valor de inicialización, ya que no se respetó la secuencia de tu framework.
Para determinar si la propiedad fue o no inicializada, llama a isInitialized
en la referencia de la propiedad.
Por ejemplo, en createScene()
puedes verificar la propiedad isInitialized
antes de acceder al controlador de video. Si no ha sido inicializada crea un controlador por defecto.
class Game {
//...
fun createScene() {
if (!this::videoController.isInitialized) {
videoController = VideoController(300, 300)
}
print(
"Resolución de ${videoController.screenWitdh}x" +
"${videoController.screenHeight}"
)
}
}
Al ejecutar el programa sin llamar a init()
tendrás:
Resolución de 300x300
Únete Al Discord De Develou
Si tienes problemas con el código de este tutorial, preguntas, recomendaciones o solo deseas discutir sobre desarrollo Android conmigo y otros desarrolladores, únete a la comunidad de Discord de Develou y siéntete libre de participar como gustes. ¡Te espero!