0Pricing
Kotlin Academy · Lekcja

Operator !!: kiedy i dlaczego go unikać

Poznaj operator asercji niepustości, związane z nim ryzyko oraz lepsze alternatywy.

Operator !!: kiedy i dlaczego go unikać to bezpłatna lekcja Kotlin Academy na CoddyKit. To lekcja 4 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 !!?

Operator asercji non-null !! konwertuje typ nullable na non-null. Jeśli w czasie działania wartość ma wartość null, zgłaszany jest wyjątek NullPointerException.

Podstawowe użycie !!

x!! zwraca x, jeśli nie ma ono wartości null, a w przeciwnym razie zgłasza wyjątek NPE.

fun main() {
    val name: String? = "Kotlin"
    val len: Int = name!!.length // 6
    println(len)
}

!! zgłasza wyjątek dla null

Jeśli wartość rzeczywiście ma wartość null, otrzymasz dokładnie ten wyjątek, któremu Kotlin próbuje zapobiegać.

fun main() {
    val name: String? = null
    try {
        println(name!!.length)
    } catch (e: NullPointerException) {
        println("NPE caught!")
    }
}

Lepsze rozwiązanie: bezpieczne wywołanie

Zamiast !! wybierz ?. — zapewnia ono łagodną obsługę bez awarii.

fun main() {
    val name: String? = null
    val len = name?.length
    println(len) // null — no crash
}

Lepsze rozwiązanie: operator Elvis

Połącz ?. z ?:, aby zapewnić rozsądną wartość domyślną.

fun main() {
    val name: String? = null
    val len = name?.length ?: 0
    println(len) // 0
}

Lepsze rozwiązanie: inteligentne rzutowanie

Sprawdzenie if (x != null) umożliwia inteligentne rzutowanie — !! nie jest potrzebne.

fun main() {
    val name: String? = "Alice"
    if (name != null) {
        println(name.length) // smart-cast to String
    }
}

Lepsze rozwiązanie: requireNotNull

Jeśli wartość musi być obecna, requireNotNull(x) { "..." } zgłasza znaczący wyjątek IllegalArgumentException.

fun process(name: String?) {
    val safe = requireNotNull(name) { "name is required" }
    println("processing $safe")
}
fun main() {
    process("Ada")
    // process(null) // throws IllegalArgumentException: name is required
}

Lepsze rozwiązanie: checkNotNull

checkNotNull(x) działa tak samo, ale zgłasza IllegalStateException — używaj go do sprawdzania niezmienników.

class Service {
    private var data: String? = null
    fun load() { data = "loaded" }
    fun read(): String = checkNotNull(data) { "load() must be called first" }
}
fun main() {
    val s = Service()
    s.load()
    println(s.read())
}

Uzasadnione zastosowania !!

Rzadkie, ale uzasadnione: gdy brak wartości null jest rzeczywistym niezmiennikiem, którego nie można dowieść w czasie kompilacji (np. po wywołaniu refleksyjnym). Dodaj komentarz wyjaśniający dlaczego.

fun main() {
    val list = listOf(1, 2, 3)
    val firstEven: Int = list.find { it % 2 == 0 }!! // safe: we know list has an even
    println(firstEven)
}

Łańcuch !! — skrajny antywzorzec

Wiele wystąpień !! w jednym łańcuchu to zapach kodu. Zrefaktoryzuj kod, używając bezpiecznych wywołań i klauzul ochronnych.

class A(val b: B?)
class B(val c: C?)
class C(val name: String?)
fun main() {
    val a: A? = A(B(C("ok")))
    // BAD: val n = a!!.b!!.c!!.name!!
    val n = a?.b?.c?.name ?: "unknown"
    println(n)
}

Usuwanie !! podczas refaktoryzacji

Zastąp !! uczciwszym API: zwracaniem wartości nullable, requireNotNull na wejściu albo wcześniejszym return.

fun firstUpper(s: String?): String? = s?.firstOrNull()?.uppercase()
fun main() {
    println(firstUpper("alice")) // A
    println(firstUpper(""))      // null
    println(firstUpper(null))    // null
}

Szybkie sprawdzenie

Co się stanie po zastosowaniu !! do wartości, która w czasie działania rzeczywiście ma wartość null?

Podsumowanie

!! to mechanizm awaryjny, który omija bezpieczeństwo null w Kotlinie. Preferuj ?., ?:, inteligentne rzutowania, requireNotNull lub checkNotNull. Używaj !! tylko w przypadku udokumentowanych niezmienników, których kompilator nie potrafi dowieść.

Często zadawane pytania

Czy lekcja „Operator !!: kiedy i dlaczego go unikać” jest bezpłatna?

Tak — pełny tekst „Operator !!: kiedy i dlaczego go unikać” 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 „Operator !!: kiedy i dlaczego go unikać”?

Poznaj operator asercji niepustości, związane z nim ryzyko oraz lepsze alternatywy. Ć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 4 z 4.

Ile czasu zajmuje lekcja „Operator !!: kiedy i dlaczego go unikać”?

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. Typy dopuszczające null i modyfikator ?
  2. Bezpieczne wywołanie ?. i Elvis ?: w rzeczywistym kodzie
  3. let, also i run z odbiorcami dopuszczającymi null
  4. Operator !!: kiedy i dlaczego go unikać
← Powrót do Kotlin Academy