0Pricing
Kotlin Academy · Lekcja

by lazy: szczegółowe omówienie odroczonej inicjalizacji

Poznaj tryby leniwej inicjalizacji: SYNCHRONIZED, PUBLICATION i NONE.

by lazy: szczegółowe omówienie odroczonej inicjalizacji to bezpłatna lekcja Kotlin Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Kotlin Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Kotlin Academy zawiera 4 lekcji w sumie.

Czym jest by lazy?

by lazy odracza inicjalizację elementu val do chwili pierwszego dostępu. Lambda jest uruchamiana raz, a jej wynik jest buforowany.

val greeting: String by lazy {
    println("Computing...")
    "Hello, Kotlin!"
}
fun main() {
    println(greeting) // prints Computing... then Hello, Kotlin!
    println(greeting) // prints Hello, Kotlin! (cached)
}

Składnia lazy

Delegat by lazy przyjmuje lambdę zwracającą typ wartości wywnioskowany z deklaracji właściwości.

val pi: Double by lazy { Math.PI }
val appName: String by lazy { "MyApp v1.0" }
fun main() {
    println(pi)      // 3.141592653589793
    println(appName) // MyApp v1.0
}

Tryb SYNCHRONIZED (domyślny)

Domyślnie lazy używa LazyThreadSafetyMode.SYNCHRONIZED: tylko jeden wątek inicjalizuje wartość.

val heavyResource: String by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
    Thread.sleep(100) // simulate work
    "Resource ready"
}
fun main() { println(heavyResource) }

Tryb PUBLICATION

PUBLICATION pozwala wielu wątkom na równoczesną inicjalizację; wygrywa pierwszy wynik. Należy go używać, gdy inicjalizacja jest tania i nie powoduje efektów ubocznych.

val config: Map<String, String> by lazy(LazyThreadSafetyMode.PUBLICATION) {
    mapOf("host" to "localhost", "port" to "8080")
}
fun main() { println(config["host"]) }

Tryb NONE

NONE nie wiąże się z narzutem synchronizacji. Należy go używać wyłącznie w kontekstach jednowątkowych, gdy wydajność ma znaczenie.

val singleThreadValue: Int by lazy(LazyThreadSafetyMode.NONE) {
    42
}
fun main() { println(singleThreadValue) }

Lazy w klasie

by lazy wewnątrz klasy inicjalizuje wartość przy pierwszym dostępie do właściwości, co przydaje się przy kosztownych obliczeniach zależnych od stanu instancji.

class DatabaseConnection(val url: String) {
    val pool: String by lazy {
        println("Connecting to $url")
        "Pool@$url"
    }
}
fun main() {
    val db = DatabaseConnection("localhost:5432")
    println(db.pool)
}

Lazy a lateinit

Należy użyć by lazy dla elementu val ze złożoną inicjalizacją. lateinit należy użyć dla elementu var przypisywanego z zewnątrz (np. w testach lub podczas wstrzykiwania zależności).

class MyService {
    val computed: List<Int> by lazy { (1..100).toList() }
    lateinit var injected: String
}
fun main() {
    val s = MyService()
    s.injected = "injected value"
    println(s.computed.size)
    println(s.injected)
}

Sprawdzanie isInitialized

Można sprawdzić, czy właściwość lazy została zainicjalizowana, za pomocą .isInitialized() — ale wyłącznie przez odwołanie do delegata.

val myLazy: String by lazy { "initialized" }
fun main() {
    val ref = ::myLazy
    // No direct isInitialized on val lazy, but we can check via delegate
    println(myLazy)
}

Lazy z zależnością

Właściwości lazy mogą odwoływać się do innych właściwości lazy, tworząc łańcuch leniwej inicjalizacji.

val baseUrl: String by lazy { "https://api.example.com" }
val usersUrl: String by lazy { "$baseUrl/users" }
val postsUrl: String by lazy { "$baseUrl/posts" }
fun main() {
    println(usersUrl)
    println(postsUrl)
}

Praktyka: usługa Singleton

Należy używać by lazy w deklaracjach object, aby inicjalizować ciężkie singletony dopiero na żądanie.

object Analytics {
    val client: String by lazy {
        println("Initializing analytics client")
        "AnalyticsClient@ready"
    }
}
fun main() {
    println("App started")
    println(Analytics.client) // initialized on first use
    println(Analytics.client) // cached
}

Leniwa kompilacja wyrażeń regularnych

Kompilowanie wyrażeń regularnych jest kosztowne. Należy użyć by lazy, aby skompilować je raz i wielokrotnie używać, unikając powtarzalnego narzutu.

val emailRegex: Regex by lazy {
    Regex("^[A-Za-z0-9+_.-]+@(.+)$")
}
fun isValidEmail(email: String) = emailRegex.matches(email)
fun main() {
    println(isValidEmail("user@example.com")) // true
    println(isValidEmail("bad-email"))         // false
}

Szybkie sprawdzenie

Którego trybu lazy należy użyć w środowisku jednowątkowym, aby uzyskać maksymalną wydajność?

Podsumowanie

by lazy uruchamia swoją lambdę raz przy pierwszym dostępie i buforuje wynik. Należy wybrać SYNCHRONIZED (domyślnie) dla bezpieczeństwa wątkowego, PUBLICATION dla współbieżnej, idempotentnej inicjalizacji oraz NONE dla wydajności w środowisku jednowątkowym.

Często zadawane pytania

Czy lekcja „by lazy: szczegółowe omówienie odroczonej inicjalizacji” jest bezpłatna?

Tak — pełny tekst „by lazy: szczegółowe omówienie odroczonej inicjalizacji” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Kotlin Academy, przejdź na CoddyKit PRO. Kurs Kotlin Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „by lazy: szczegółowe omówienie odroczonej inicjalizacji”?

Poznaj tryby leniwej inicjalizacji: SYNCHRONIZED, PUBLICATION i NONE. Ćwiczysz Kotlin Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Kotlin Academy?

Nie wymagamy żadnego doświadczenia. Kotlin Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.

Ile czasu zajmuje lekcja „by lazy: szczegółowe omówienie odroczonej inicjalizacji”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Kotlin Academy?

Tak. Każda lekcja Kotlin Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. by lazy: szczegółowe omówienie odroczonej inicjalizacji
  2. Delegaty observable i vetoable
  3. Pisanie własnego delegata ReadWriteProperty
  4. Delegaty dla Preferences, właściwości opartych na Map i logowania
← Powrót do Kotlin Academy