lateinit e inicialización diferida
Use lateinit para propiedades asignadas posteriormente y by lazy para cálculos diferidos.
lateinit e inicialización diferida es una lección gratuita de Kotlin Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Kotlin Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Kotlin Academy incluye 4 lecciones en total.
Dos herramientas para la configuración diferida
A veces no puede inicializar una propiedad en el momento de construir el objeto. Kotlin proporciona lateinit (para var, asignada más adelante) y by lazy (para val, calculada en el primer acceso).
Conceptos básicos de lateinit
lateinit var pospone la inicialización. La variable debe ser una var no nula y no primitiva. Acceder a ella antes de asignarle un valor lanza UninitializedPropertyAccessException.
class Service {
lateinit var name: String
fun init(value: String) { name = value }
}
fun main() {
val s = Service()
s.init("MyService")
println(s.name)
}¿Por qué utilizar lateinit?
Utilice lateinit para la inyección de dependencias, los accesorios de prueba o los ciclos de vida administrados por frameworks (vistas de Android y beans de Spring), cuando la inicialización se realiza fuera del constructor.
class Repository {
lateinit var db: String // assigned later by DI framework
fun query() = "querying $db"
}
fun main() {
val r = Repository()
r.db = "postgres://localhost"
println(r.query())
}Comprobación de isInitialized
Puede comprobar si se ha asignado un valor a una propiedad lateinit mediante ::propName.isInitialized.
class Foo {
lateinit var bar: String
fun status() = if (::bar.isInitialized) "set to $bar" else "unset"
}
fun main() {
val f = Foo()
println(f.status()) // unset
f.bar = "hi"
println(f.status())
}Restricciones de lateinit
No puede utilizar lateinit con tipos primitivos (Int, Boolean, etc.), tipos anulables ni val. El compilador hace cumplir estas reglas.
// VALID:
lateinit var name: String
// INVALID:
// lateinit var count: Int // primitives not allowed
// lateinit val constant: String // val not allowed
// lateinit var maybe: String? // nullable not allowed
fun main() { name = "ok"; println(name) }Conceptos básicos de by lazy
by lazy pospone la inicialización de un val hasta el primer acceso. La lambda se ejecuta una vez y el resultado se almacena en caché.
val expensive: String by lazy {
println("Computing...")
"result"
}
fun main() {
println(expensive) // Computing... then result
println(expensive) // result (cached)
}¿Por qué utilizar by lazy?
Utilice by lazy cuando la inicialización sea costosa y quizá no sea necesaria (almacene el resultado en caché para usarlo más adelante), o cuando la inicialización dependa de otras propiedades ya construidas.
class Config {
val parsed: Map<String, String> by lazy {
println("parsing config...")
mapOf("host" to "localhost", "port" to "8080")
}
}
fun main() {
val c = Config()
println("config object created — not parsed yet")
println(c.parsed["host"]) // now parses
println(c.parsed["port"]) // cached
}Modos de seguridad de subprocesos de lazy
De forma predeterminada, by lazy utiliza LazyThreadSafetyMode.SYNCHRONIZED. Utilice PUBLICATION para una inicialización apta para la concurrencia y NONE para obtener rendimiento en aplicaciones de un solo subproceso.
val safe: String by lazy { "thread-safe" }
val fast: String by lazy(LazyThreadSafetyMode.NONE) { "fast, single-thread" }
fun main() {
println(safe)
println(fast)
}lateinit frente a lazy
lateinit: var asignada externamente. by lazy: val calculado por la propia propiedad en el primer acceso.
class Demo {
lateinit var injected: String // assigned by caller
val computed: String by lazy { "computed once" }
}
fun main() {
val d = Demo()
d.injected = "from outside"
println(d.injected)
println(d.computed)
}Lectura de otras propiedades con lazy
Una propiedad lazy puede leer otras propiedades (inicializadas anteriormente) y combinarlas.
class User(val first: String, val last: String) {
val fullName: String by lazy { "$first $last" }
}
fun main() {
val u = User("Ada", "Lovelace")
println(u.fullName)
}Patrón práctico
Combine lateinit para la inyección de dependencias y by lazy para el estado derivado dentro de la misma clase.
class App {
lateinit var config: Map<String, String>
val host: String by lazy { config["host"] ?: "localhost" }
}
fun main() {
val app = App()
app.config = mapOf("host" to "api.example.com")
println(app.host) // api.example.com
}Comprobación rápida
¿Qué palabra clave pospone la inicialización de una propiedad val hasta el primer acceso?
Resumen
Utilice lateinit var para propiedades mutables no nulas asignadas más adelante por frameworks o mediante inyección de dependencias. Utilice val by lazy para valores de solo lectura que deban calcularse una vez en el primer acceso. Compruebe el estado con ::prop.isInitialized.
Aprende Kotlin con un tutor de IA — gratis
Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.
- Cursos
- 51
- Lecciones
- 203
Preguntas frecuentes
¿La lección «lateinit e inicialización diferida» es gratis?
Sí — el texto completo de «lateinit e inicialización diferida» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Kotlin Academy, actualiza a CoddyKit PRO. El curso de Kotlin Academy incluye 4 lecciones en total.
¿Qué aprenderé en «lateinit e inicialización diferida»?
Use lateinit para propiedades asignadas posteriormente y by lazy para cálculos diferidos. Practicas Kotlin Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Kotlin Academy?
No se requiere experiencia previa. Kotlin Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «lateinit e inicialización diferida»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Kotlin Academy?
Sí. Cada lección de Kotlin Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Constructor primario y parámetros de propiedades
- Bloques init y orden de inicialización
- Getters y setters personalizados con field
- lateinit e inicialización diferida