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