Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Kotlin
Code

Kotlin From Scratch: обработка исключений

by
Difficulty:IntermediateLength:MediumLanguages:
This post is part of a series called Kotlin From Scratch.
Kotlin From Scratch: Abstract Classes, Interfaces, Inheritance, and Type Alias

Russian (Pусский) translation by Ilya Nikov (you can also view the original English article)

Kotlin - это современный язык программирования, который компилируется в байт-код Java. Он бесплатный и с открытым исходным кодом, и делает кодирование для Android еще более увлекательным.

В предыдущей статье вы узнали больше об объектно-ориентированном программировании, углубившись в абстрактные классы, интерфейсы, наследование и псевдонимы типов в Kotlin.

В этом посте вы продолжите изучать программирование в Kotlin, изучая исключения и способы их обработки.

1. Обработка исключений

Исключения используются для обозначения проблемы в нашем коде во время выполнения программы. Обработка исключений - это возможность адресовать (или обрабатывать) исключение, которое может произойти. Если мы не обработаем возникшее исключение, наша программа внезапно прекратит выполнение, что приведет к немедленному завершению работы приложения.

Обработка исключений позволяет нашей программе продолжать выполнение, даже если было исключение (хотя настоятельно рекомендуется регистрировать ваши исключения и сообщать о них с помощью инструмента отчетности о сбоях, такого как Crashlytics).

В Java у нас есть два вида исключений: проверенные и непровереные. Я кратко объясню оба из них, но мы начнем с непроверенных исключений.

Непроверенные исключения

Это исключения, которые вызываются из-за недостатков в вашем коде. Они являются прямым или косвенным подклассом суперкласса RuntimeException.

Примеры непроверенных исключений включают в себя:

  • ArithmeticException: бросается, когда вы делите на ноль.
  • ArrayIndexOutOfBoundExceptions: создается при обращении к массиву с недопустимым индексом.
  • SecurityException: выбрасывается менеджером безопасности, чтобы указать на нарушение безопасности.
  • NullPointerException: выдается при вызове метода или свойства для нулевого объекта.

Метод, который может выдать непроверенное исключение, не содержит никакой информации об исключении, выданном в его объявлении метода.

Эти типы исключений могут быть предотвращены путем правильного кодирования. В приведенном выше коде мы должны были проверить, был ли знаменатель равен нулю, прежде чем выполнять операцию. Для этих исключений разработчику не нужно перехватывать исключение с помощью блока try ... catch. Другими словами, компилятор не заставляет нас переносить код, который может вызвать исключение, в блок try ... catch. Вместо этого мы должны просто убедиться, что исключения никогда не возникают.

Кроме того, помните, что Kotlin - это абсолютно безопасный язык. Другими словами, это может помочь нам избежать появления исключений NullPointerException в нашем коде. Вы можете прочитать статью Nullability, Loops, and Condition, чтобы узнать больше о нулевой безопасности в Kotlin.

Проверенные исключения в Java

Метод, который может генерировать проверенное исключение, должен быть объявлен в сигнатуре метода с использованием ключевого слова throws. Если вы вызываете метод, который генерирует проверенное исключение, вам нужно либо снова выбросить его из вашей функции, либо перехватить его и обработать, используя блок try ... catch.

Проверенные исключения - это исключения, которые проверяются во время компиляции. Эти виды исключений наследуются от класса Exception. Примером такого рода исключения является IOException. Это может произойти, когда вы пытаетесь получить доступ к файлу, который не может быть открыт, потому что он не существует. (FileNotFoundException является подклассом IOException.)

В предыдущем коде мы использовали блок try ... catch для обработки IOException внутри метода editFile(). Теперь мы можем вызвать метод editFile() как обычно, и компилятор не будет жаловаться.

Глядя на код ниже, мы реорганизовали метод, чтобы вместо него использовать ключевое слово throws в сигнатуре метода. Это указывает вызывающим абонентам, что им необходимо обработать исключение IOException, которое может быть вызвано при вызове метода editFile().

Чтобы вызвать метод, описанный выше, нам нужно поместить его в блок try ... catch для обработки исключения.

Это был краткий обзор исключений в Java. Давайте теперь посмотрим, как Kotlin обрабатывает исключения.

2. Исключения в Kotlin

Основное различие между механизмами исключений Kotlin и Java заключается в том, что все исключения не проверяются в Kotlin. Другими словами, они не объявлены явно в сигнатурах функций, как в Java.

Здесь мы преобразовали метод editFile() в функцию Kotlin. Вы можете видеть, что функция не имеет оператора throws IOException в своей сигнатуре функции. throws даже не ключевое слово в Kotlin.

Также мы можем вызвать эту функцию, не окружая ее блоком try ... catch, и компилятор не будет жаловаться. Другими словами, в Kotlin нет такой вещи, как проверенные исключения. Все исключения не проверены. (Обратите внимание, что при возникновении исключения выполнение программы будет остановлено как обычно.)

Если мы думаем, что это исключение может возникнуть, мы все равно должны обработать его, окружив метод блоком try ... catch, но это не обеспечивается компилятором Kotlin.

Если исключение, выброшенное внутри функции editFile(), является экземпляром класса IOException, наш блок catch будет выполнен, и мы просто выведем трассировку стека для целей отладки.

Блок try...catch

Конструкция try с предложениями catch и finally в Kotlin похожа на Java.

Здесь мы бросаем объект Exception в блок try. Обратите внимание, что мы не включили ключевое слово new, как в Java, чтобы создать новый экземпляр. Также обратите внимание, что мы не указали исключение, которое будет выброшено в сигнатуре функции, как в случае с Java.

Мы обрабатываем все подклассы и классы типа Exception в блоке catch. Необязательный блок finally всегда выполняется - здесь мы обычно закрываем любые ранее открытые ресурсы или соединения, чтобы предотвратить утечку ресурсов. Например, если вы открываете файл или создаете базу данных или сетевое соединение в блоке try, вы должны закрыть или освободить его в блоке finally.

Обратите внимание, что в Kotlin конструкция throw является выражением и может сочетаться с другими выражениями.

Кроме того, конструкция try может использоваться как выражение.

Здесь мы присвоили значение, возвращаемое из блока try ... catch, переменной result. Если число не равно 1, генерируется исключение IllegalArgumentException и выполняется блок catch. false выражение в значении блока catch будет присвоено переменной result. Если вместо этого число равно 1, то значение true будет присвоено переменной result.

Java Interop

Исключения в Kotlin ведут себя как обычно в Java, но я хочу, чтобы вы знали о полезной аннотации под названием @Throws в Kotlin, которая может пригодиться. Поскольку все исключения в Kotlin не проверены, разработчики, использующие ваш код Kotlin из Java, могут не знать, что ваши функции генерируют исключения. Однако вы все равно можете добавить возможные исключения, которые могут быть выброшены в сигнатуру метода с аннотацией @Throw. Это предупредит Java-абонентов, что им нужно обработать исключение.

Давайте посмотрим на практический пример этой аннотации.

Здесь мы определили функцию Kotlin, которая может генерировать исключение IllegalArgumentException, только если тип, передаваемый в функцию, не имеет тип Int.

Мы вызываем эту функцию верхнего уровня addNumberToTwo() непосредственно из Java следующим образом:

Это отлично работает; компилятор не жалуется. Однако, если мы хотим сообщить вызывающим Java, что функция верхнего уровня addNumberToTwo() выдает исключение, мы просто добавляем аннотацию @Throws к сигнатуре функции.

Эта аннотация @Throws может принимать разделенный запятыми список аргументов классов исключений. В приведенном выше коде мы просто включили один класс исключений - IllegalArgumentException.

Теперь мы должны обновить ваш Java-код для обработки исключения.

Если мы декомпилируем функцию Kotlin addNumberToTwo(), используя функцию Показать байт-код Kotlin (если вы находитесь в IntelliJ IDEA или Android Studio, используйте Инструменты> Kotlin> Показать байт-код Kotlin), мы увидим следующий код Java:

В сгенерированном Java-коде выше (некоторые элементы сгенерированного кода были удалены для краткости), вы можете видеть, что компилятор добавил ключевое слово throws в сигнатуру метода - потому что мы включили аннотацию @Throws.

Заключение

В этом уроке вы узнали больше о программировании на Kotlin, изучив исключения. Мы видели, что у Kotlin нет проверенных исключений, но вместо этого все исключения не проверены. Мы также рассмотрели, как обрабатывать исключения с помощью блока try ... catch, и увидели полезность аннотации @Throws в Kotlin для вызывающих Java-программ.

Чтобы узнать больше о языке Kotlin, я рекомендую посетить документацию Kotlin. Или ознакомьтесь с некоторыми другими нашими статьями по разработке приложений для Android здесь, на Envato Tuts!


Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.