Kotlin Academy · Lezione

lateinit e inizializzazione lazy

Utilizzi lateinit per le proprietà assegnate successivamente e by lazy per i calcoli differiti.

Lezione 4 di 413 passaggi

lateinit e inizializzazione lazy è una lezione Kotlin Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Kotlin Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Kotlin Academy include 4 lezioni in totale.

Due strumenti per l'inizializzazione differita

A volte non è possibile inizializzare una proprietà al momento della costruzione. Kotlin offre lateinit (per var, assegnato in seguito) e by lazy (per val, calcolato al primo accesso).

Nozioni di base su lateinit

lateinit var rimanda l'inizializzazione. La variabile deve essere un var non nullo e non primitivo. L'accesso prima dell'assegnazione genera UninitializedPropertyAccessException.

class Service {
    lateinit var name: String
    fun init(value: String) { name = value }
}
fun main() {
    val s = Service()
    s.init("MyService")
    println(s.name)
}

Perché usare lateinit?

Usi lateinit per l'iniezione delle dipendenze, i fixture di test o i cicli di vita gestiti dal framework (viste Android, bean Spring), quando l'inizializzazione avviene al di fuori del costruttore.

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())
}

Controllo di isInitialized

Può verificare se una proprietà lateinit è stata assegnata 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())
}

Limitazioni di lateinit

Non è possibile usare lateinit con tipi primitivi (Int, Boolean, ecc.), tipi nullable o val. Il compilatore applica queste regole.

// 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) }

Nozioni di base su by lazy

by lazy rimanda l'inizializzazione di un val fino al primo accesso. La lambda viene eseguita una volta e il risultato viene memorizzato nella cache.

val expensive: String by lazy {
    println("Computing...")
    "result"
}
fun main() {
    println(expensive) // Computing... then result
    println(expensive) // result (cached)
}

Perché usare by lazy?

Usi by lazy quando l'inizializzazione è costosa e potrebbe non essere necessaria (memorizzandone il risultato per usarlo in seguito), oppure quando dipende da altre proprietà già costruite.

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
}

Modalità di sicurezza dei thread di lazy

Per impostazione predefinita, by lazy usa LazyThreadSafetyMode.SYNCHRONIZED. Usi PUBLICATION per un'inizializzazione compatibile con l'accesso concorrente e NONE per le prestazioni in applicazioni a thread singolo.

val safe: String by lazy { "thread-safe" }
val fast: String by lazy(LazyThreadSafetyMode.NONE) { "fast, single-thread" }
fun main() {
    println(safe)
    println(fast)
}

lateinit vs lazy

lateinit: var, assegnato esternamente. by lazy: val, calcolato dalla proprietà stessa al primo accesso.

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)
}

Lettura di altre proprietà con lazy

Una proprietà lazy può leggere altre proprietà (inizializzate in precedenza) e combinarle.

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)
}

Schema pratico

Combini lateinit per la DI e by lazy per lo stato derivato nella stessa 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 rapida

Quale parola chiave rimanda l'inizializzazione di una proprietà val fino al primo accesso?

Riepilogo

Usi lateinit var per proprietà mutabili non nullable assegnate in seguito da framework o DI. Usi val by lazy per valori di sola lettura che devono essere calcolati una volta al primo accesso. Verifichi lo stato con ::prop.isInitialized.

Gratis per iniziare

Impara Kotlin con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
51
Lezioni
203

Domande Frequenti

La lezione «lateinit e inizializzazione lazy» è gratuita?

Sì — il testo completo di «lateinit e inizializzazione lazy» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Kotlin Academy, passa a CoddyKit PRO. Il corso Kotlin Academy include 4 lezioni in totale.

Cosa imparerò in «lateinit e inizializzazione lazy»?

Utilizzi lateinit per le proprietà assegnate successivamente e by lazy per i calcoli differiti. Eserciti Kotlin Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Kotlin Academy?

Non è richiesta alcuna esperienza precedente. Kotlin Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «lateinit e inizializzazione lazy»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Kotlin Academy?

Sì. Ogni lezione Kotlin Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Costruttore primario e parametri delle proprietà
  2. Blocchi init e ordine di inizializzazione
  3. Getter e setter personalizzati con field
  4. lateinit e inizializzazione lazy
← Torna a Kotlin Academy