W Kotlin obsługa wyjątków jest realizowana za pomocą konstrukcji try/catch/finally, ale różni się od podejścia Java skupieniem na Unchecked Exceptions i zwięzłą składnią. Ważna różnica polega na tym, że w Kotlinie brak jest checked exceptions, co odciąża programistę od obowiązkowego wskazywania throws i przechwytywania takich wyjątków.
Java używa checked/unchecked exceptions, gdzie checked wymagają jawnego przechwytywania lub deklaracji. Często prowadzi to do nadmiarowego boilerplate'u i kłopotliwego kodu. Kotlin zaprojektowano prościej — wszystkie wyjątki są zazwyczaj unchecked (dziedziczące po RuntimeException), co ułatwia obsługę i czyni kod bardziej czytelnym.
Programiści Java w Kotlinie próbują przechwytywać i wskazywać checked exceptions — kod kompiluje się, ale sens się zatraca. Ponadto, użycie finally bez świadomości niuansów prowadzi do wycieków lub nie działającego kodu.
Używamy try/catch/finally w Kotlin w sposób zwięzły i rzeczowy:
fun process(data: String): Int = try { data.toInt() } catch (e: NumberFormatException) { 0 } finally { println("Processing done") }
Kluczowe cechy:
Co się dzieje, jeśli wyjątek zostanie wyrzucony w bloku finally? Jak to wpływa na zwracanie wartości?
Wyjątki wyrzucone z finally zawsze przesłaniają wszelkie inne wyjątki lub return z bloku try/catch, co może prowadzić do utraty ważnych danych o przyczynie awarii.
fun demo(): Int = try { 1 } finally { throw RuntimeException("error in finally") }
Czy try/catch może być wyrażeniem w Kotlinie? Czym różni się od Java?
Tak. try/catch/finally w Kotlinie to wyrażenia, więc mogą zwracać wynik i być używane w miejscach, gdzie dozwolone są wartości.
val value = try { risky() } catch (e: Exception) { fallback() }
W Java to tylko operatory.
Czy konieczne jest przechwytywanie wyjątków w Kotlinie, jeśli wywoływana jest zewnętrzna funkcja Java z throws?
Nie. Ponieważ checked exceptions są ignorowane przez kompilator Kotlin: można ich nie przechwytywać jawnie, ale mogą one być nadal wyrzucane w trakcie wykonywania.
Wstawiają catch (e: Exception) wszędzie, nie różnicując prawdziwych i oczekiwanych błędów. Używają finally do zwracania wartości, co prowadzi do nieoczekiwanego zachowania w przypadku błędów.
Zalety:
Wady:
Używają przechwytywania tylko oczekiwanych błędów, finally tylko do czyszczenia zasobów, a try/catch traktują jako wyrażenia tam, gdzie zwiększa to czytelność.
Zalety:
Wady: