Jedną z pierwszych rzeczy jaką się dowiedziałem o Kotlinie było to, że jest on "Null Safety", że nie można przez przypadek i niedopatrzenie doprowadzić do wywołania NullPointerException. W jaki sposób jest to zrealizowane?
Każdy typ domyślnie jest non-null (nie można przypisać mu wartości null). Kompilator będzie sygnalizował każdą taką sytuację błędem. Na przykład:
var text: String = "tekst"
text = null
spowoduje błąd kompilacji.
Czyli używając kotlina nigdy nie spotkamy nulli?
Niestety nie. Nulle są dalej obecne, ale mechanizm obrony przed NullPointerException jest lepszy. Każdą zmienną możemy uczynić nullable (czyli taką do której nulla da radę przypisać) dodając znak "?" na końcu typu:
var possibleNullText: String? = null
Jeżeli teraz chcielibyśmy sprawdzić długość tekstu w zmiennej possibleNullText kompilator nie pozwoli nam wprost odwołać się do pola length. Musimy użyć pytajnika (operatora bezpiecznego dostępu):
val textLength = possibleNullText?.length
Dzięki temu, jeżeli nawet possibleNullText jest nullem, wyjątek nie zostanie rzucony. Do zmiennej textLength (która to będzie typu Int?) zapisze się null. Jeżeli nie chcemy żeby textLength był nullable to użyjemy operatora Elvisa (?:)
val textLength = possibleNullText?.length ?: 0
Teraz jeżeli possibleNullText jest nullem to possibleNullText będzie miał wartość 0. W javie, aby to osiągnąć musielibyśmy użyć java.util.Optional.
Zatem, czy w kotlinie istnieje NullPointerException?
Tak, np:
- można samemu go wyrzucić
- można użyć operatora: "!!", pozbywamy się wtedy null safety - lepiej nie używać, nawet jak jest się pewnym że null nie wystąpi.