На этом шаге мы рассмотрим реализацию механизма обработки исключений.
Исключения деструктивны, какими и должны быть, - они представляют ошибочное состояние, которое надо исправить. Kotlin позволяет обрабатывать исключения, поместив код, в котором они могут возникнуть, в оператор try/catch. Синтаксис try/catch похож на синтаксис if/else. Чтобы увидеть, как работает try/catch, воспользуемся им в SwordJuggler.kt для защиты от опасных операций.
fun main() { var swordsJuggling: Int? = null val isJugglingProficient = (1..3).shuffled().last() == 3 if (isJugglingProficient) { swordsJuggling = 2 } try { proficiencyCheck(swordsJuggling) swordsJuggling = swordsJuggling!!.plus(1) } catch (e: Exception) { print(e) } println("You juggle $swordsJuggling swords!") } fun proficiencyCheck(swordsJuggling: Int?) { swordsJuggling ?: throw IllegalStateException("Player cannot juggle swords") } class UnskilledSwordJugglerException() : IllegalStateException("Player cannot juggle swords")
Рис.1. Добавление оператора try/catch (SwordJuggler.kt)
Добавив оператор try/catch, вы определили, что будет происходить, если какое-то значение не null, и что - если null. В блоке try вы "пытаетесь" использовать переменную. Если исключение не появится, оператор try выполнится, а оператор catch нет. Эта логика ветвления подобна условию if/else. В этом случае вы пытаетесь добавить еще один меч к тем, которыми уже жонглируете, используя оператор !!..
В блоке catch вы определили, что случится, если выражение в блоке try вызовет исключение. Блок catch принимает аргумент с определенным типом исключения, от которого нужно защититься. В этом случае вы перехватываете любые исключения типа Exception.
Блок catch может включать любую логику, но в нашем примере все просто. Блок catch просто выводит имя исключения.
Внутри блока try строки кода выполняются последовательно. В этом случае, если swordsJuggling имеет значение, отличное от null, функция plus() прибавит 1 к swordsJuggling без проблем, и в консоли появится сообщение:
You juggle 3 swords!
Если вы недостаточно сноровисты в жонглировании, переменная swordsJuggling будет иметь значение null и proficiencyCheck() возбудит UnskilledSwordJugglerException. Но так как исключение возникнет внутри оператора try/catch, программа продолжит работу и выполнит блок catch, отправив следующее сообщение в консоль:
UnskilledSwordJugglerException: Player cannot Juggle swords You juggle null swords!
Обратите внимание, что в консоли появилось и имя исключения, и строка You juggle null swords!. Это существенная деталь, так как последняя строка выводится после выполнения блока try/catch. Необработанное исключение вызовет сбой и остановит выполнение программы. Но так как вы обработали исключение блоком try/catch, выполнение кода продолжилось так, как будто опасная операция никогда и не выполнялась.
Запустите SwordJuggler.kt несколько раз, чтобы увидеть все исходы.
На следующем шаге мы рассмотрим проверку условий.