lateinit e inicialização tardia
Use lateinit para propriedades atribuídas posteriormente e by lazy para computação adiada.
lateinit e inicialização tardia é uma aula grátis de Kotlin Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Kotlin Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Kotlin Academy inclui 4 aulas no total.
Duas ferramentas para configuração tardia
Às vezes, não é possível inicializar uma propriedade no momento da construção. O Kotlin oferece lateinit (para var, atribuído posteriormente) e by lazy (para val, calculado no primeiro acesso).
Noções básicas de lateinit
lateinit var adia a inicialização. A variável deve ser um var não nulo e não primitivo. O acesso antes da atribuição lança 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 que usar lateinit?
Use lateinit para injeção de dependências, dados de teste ou ciclos de vida gerenciados por estruturas (visualizações do Android, beans do Spring), nos quais a inicialização ocorre fora do construtor.
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())
}Verificação de isInitialized
Você pode verificar se uma propriedade lateinit foi atribuída usando ::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())
}Restrições de lateinit
Você não pode usar lateinit em tipos primitivos (Int, Boolean etc.), tipos anuláveis ou val. O compilador impõe essas regras.
// 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) }Noções básicas de by lazy
by lazy adia a inicialização de um val até o primeiro acesso. A lambda é executada uma vez, e o resultado é armazenado em cache.
val expensive: String by lazy {
println("Computing...")
"result"
}
fun main() {
println(expensive) // Computing... then result
println(expensive) // result (cached)
}Por que usar by lazy?
Use by lazy quando a inicialização for dispendiosa e talvez não seja necessária (armazene-a em cache para uso posterior) ou quando a inicialização depender de outras propriedades já construídas.
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 segurança de threads de lazy
Por padrão, by lazy usa LazyThreadSafetyMode.SYNCHRONIZED. Use PUBLICATION para uma inicialização segura em execução concorrente e NONE para obter desempenho em execução com uma única thread.
val safe: String by lazy { "thread-safe" }
val fast: String by lazy(LazyThreadSafetyMode.NONE) { "fast, single-thread" }
fun main() {
println(safe)
println(fast)
}lateinit versus lazy
lateinit: var, atribuído externamente. by lazy: val, calculado pela própria propriedade no primeiro acesso.
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)
}lazy lendo outras propriedades
Uma propriedade lazy pode ler outras propriedades (inicializadas anteriormente) e combiná-las.
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)
}Padrão prático
Combine lateinit para DI e by lazy para estado derivado na mesma classe.
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
}Verificação rápida
Qual palavra-chave adia a inicialização de uma propriedade val até o primeiro acesso?
Recapitulação
Use lateinit var para propriedades mutáveis não nulas atribuídas posteriormente por estruturas ou por DI. Use val by lazy para valores somente leitura que devem ser calculados uma vez no primeiro acesso. Verifique o estado com ::prop.isInitialized.
Perguntas Frequentes
A aula “lateinit e inicialização tardia” é grátis?
Sim — o texto completo de “lateinit e inicialização tardia” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Kotlin Academy, atualize para CoddyKit PRO. O curso de Kotlin Academy inclui 4 aulas no total.
O que vou aprender em “lateinit e inicialização tardia”?
Use lateinit para propriedades atribuídas posteriormente e by lazy para computação adiada. Você pratica Kotlin Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Kotlin Academy?
Nenhuma experiência prévia é necessária. Kotlin Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “lateinit e inicialização tardia”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Kotlin Academy?
Sim. Cada aula de Kotlin Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Construtor primário e parâmetros de propriedades
- Blocos init e ordem de inicialização
- Getters e setters personalizados com field
- lateinit e inicialização tardia