try {
} catch (ex: MyException1, MyException2 ) {
logger.warn("", ex)
}
lub
try {
} catch (ex: MyException1 | MyException2 ) {
logger.warn("", ex)
}
W wyniku tego błędu kompilacji: Unresolved reference: MyException2
.
Jak mogę złapać wiele wyjątków w tym samym czasie na Kotlinie?
pdvrieze
odpowiedź tutaj:This certainly works, but is slightly less efficient as the caught exception is explicit to the jvm (so a non-processed exception will not be caught and rethrown which would be the corollary of your solution)
else
Klauzula ponownie zgłasza niechciany wyjątek.Aby dodać do odpowiedzi miensol : chociaż multi-catch w Kotlinie nie jest jeszcze obsługiwany, istnieje więcej alternatyw, o których należy wspomnieć.
Oprócz tego
try-catch-when
można również zaimplementować metodę naśladowania wielokrotnego przechwytywania. Oto jedna opcja:fun (() -> Unit).catch(vararg exceptions: KClass<out Throwable>, catchBlock: (Throwable) -> Unit) { try { this() } catch (e: Throwable) { if (e::class in exceptions) catchBlock(e) else throw e } }
A użycie tego wyglądałoby tak:
fun main(args: Array<String>) { // ... { println("Hello") // some code that could throw an exception }.catch(IOException::class, IllegalAccessException::class) { // Handle the exception } }
Będziesz chciał użyć funkcji do wytworzenia lambda zamiast używać surowej lambdy, jak pokazano powyżej (w przeciwnym razie dość szybko napotkasz „MANY_LAMBDA_EXPRESSION_ARGUMENTS” i inne problemy). Coś takiego
fun attempt(block: () -> Unit) = block
mogłoby zadziałać.Oczywiście możesz chcieć łączyć obiekty zamiast lambd, aby skomponować swoją logikę bardziej elegancko lub zachowywać się inaczej niż zwykły stary try-catch.
Zalecałbym używanie tego podejścia zamiast miensol , jeśli dodajesz jakąś specjalizację . W przypadku prostych zastosowań typu multi-catch
when
najprostszym rozwiązaniem jest wyrażenie.źródło
exceptions
przyjmuje obiekty.Przykład z aro jest bardzo dobry, ale jeśli istnieją spadki, nie będzie działać tak, jak w Javie.
Twoja odpowiedź zainspirowała mnie do napisania funkcji rozszerzenia. Aby zezwolić na klasy dziedziczone, musisz sprawdzać,
instance
a nie bezpośrednio porównywać.inline fun multiCatch(runThis: () -> Unit, catchBlock: (Throwable) -> Unit, vararg exceptions: KClass<out Throwable>) { try { runThis() } catch (exception: Exception) { val contains = exceptions.find { it.isInstance(exception) } if (contains != null) catchBlock(exception) else throw exception }}
Aby zobaczyć, jak korzystać, możesz zajrzeć do mojej biblioteki na GitHub tutaj
źródło