Шаг 74.
Основы Kotlin.
Null-безопасность и исключения. Исключения. Обработка исключений

    На этом шаге мы рассмотрим реализацию механизма обработки исключений.

    Исключения деструктивны, какими и должны быть, - они представляют ошибочное состояние, которое надо исправить. 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 несколько раз, чтобы увидеть все исходы.

    На следующем шаге мы рассмотрим проверку условий.




Предыдущий шаг Содержание Следующий шаг