Содержание
Исключение – это нежелательная ситуация, которая возникает во время выполнения программы и нарушает нормальный ход ее работы.
Такая ситуация может возникнуть, например, при попытке чтения из несуществующего файла, делении на ноль, сбое устройства и так далее. Исключение можно перехватить, чтобы принять соответствующие меры.
Приведем пример кода, в котором возникает исключение.
class ExceptionTest{ // Метод принимает два целых числа // и возвращает результат деления // первого на второе static float divide(int x, int y){ float result = x / y; return result; } public static void main(String args[]){ // Эта строка будет выполнена System.out.println(divide(4, 2)); // Эта тоже System.out.println(divide(0, 2)); // Эта выбросит исключение System.out.println(divide(4, 0)); } }
Если его запустить, получим следующий вывод:
2.0 0.0 Exception in thread "main" java.lang.ArithmeticException: / by zero at ExceptionTest.divide(ExceptionTest.java:6) at ExceptionTest.main(ExceptionTest.java:16)
Выводятся два результата деления и сообщение об исключении. В этом сообщении указана следующая информация:
Курсы по изучению Java от наших друзей Mate Academy и Hillel, помогут вам разобраться не только в основах языка программирования, но и в тонкостях работы с ним.
Для перехвата исключительных ситуаций создается объект исключения, который передается среде выполнения. Он содержит информацию об ошибке, в том числе ее тип и состояние программы на момент возникновения ошибки. Создание объекта исключения и его передача среде выполнения называется выбрасыванием исключительной ситуации.
Для перехвата исключения используется конструкция try–catch. Код, который нужно проверить на исключение, заключается в блок try, а код, обрабатывающий исключение – в блок catch.
Добавим эти блоки в приведенный выше блок кода и дополним его парой переменных для наглядности.
class ExceptionTest{ // Метод принимает два целых числа // и возвращает результат деления // первого на второе static float divide(int x, int y){ float result = x / y; return result; } public static void main(String args[]){ int x = 4; int y = 2; try { // Эта строка будет выполнена System.out.println(divide(x, y)); x = 0; // Эта тоже System.out.println(divide(x, y)); x = 4; y = 0; // Эта выбросит исключение System.out.println(divide(x, y)); } catch (ArithmeticException e) { System.out.println("Ошибка при делении " + x + " на " + y); } } }
Получим более удобочитаемый вывод:
2.0 0.0 Ошибка при делении 4 на 0
Блок finally выполняется после try-catch, независимо от того, возникло ли исключение. Это необязательный блок, но если нет блока catch, то блок finally необходим.
В этом блоке можно, например, закрыть файл, открытый в блоке try, как в приведенном ниже коде.
import java.io.FileWriter; import java.io.IOException; public class FinallyTest { public static void main(String[] args) { FileWriter writer = null; try { writer = new FileWriter("out.txt"); writer.write("Writing to the file!"); System.out.println("Файл записан успешно."); } catch (IOException e) { System.out.println("Ошибка записи в файл."); e.printStackTrace(); } finally { if ( writer != null ){ try{ writer.close(); } catch (IOException e) { System. out.println("Ошибка закрытия файла."); e.printStackTrace(); } } } } }
В некоторых случаях требуется выбросить исключение самостоятельно. Это делается при помощи ключевого слова throw.
В данном примере метод PrintMe выбрасывает исключение, если его аргумент равен null.
import java.util.LinkedList; public class ThrowTest { public static void main(String[] args) { LinkedList<String> fruits = new LinkedList<String>(); fruits.add("apple"); fruits.add("banana"); fruits.add("orange"); fruits.add("mango"); // Печатает список ThrowTest.PrintMe(fruits); // Выбрасывает исключение ThrowTest.PrintMe(null); } public static void PrintMe(LinkedList<String> fruits){ if (fruits == null){ throw new NullPointerException("Аргумент не инициализирован"); } System.out.println(fruits); } }
Ключевое слово throws используется, чтобы в сигнатуре метода указать, что он выбрасывает исключение. Его можно использовать, чтобы передавать исключения по стеку вызовов и указать, что эти исключения не обязательно должны обрабатываться в методе, в котором они объявлены.
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class ThrowsTest{ public static void readFromFile() throws IOException { // Указываем несуществующий файл, чтобы проверить работу исключения try (BufferedReader reader = new BufferedReader(new FileReader("out.txt"))) { String line; while ((line = reader.readLine()) != null) { System.out.println(line + "\n"); } } } public static void main(String[] args) { try { readFromFile(); } catch (IOException ioe) { System.out.println("Файл не найден"); } } }
Исключения в Java делятся на две основные категории: встроенные и пользовательские.
Встроенные исключения – это исключения, которые заранее определены в Java.
Когда возникает встроенное исключение, виртуальная машина Java (JVM) создает объект, принадлежащий классу встроенного исключения. Все исключения происходят от класса java.lang.Throwable, но они определены в нескольких пакетах.
Класс Throwable происходит непосредственно об класса Object и является корневым классом дерева классов исключений. От него происходят два подкласса: Error и Exception. Ошибки и исключения, которые встречаются в программах на Java, являются объектами этих классов.
С использованием класса Throwable можно создавать собственные исключения.
Класс Error является надклассом для всех классов ошибок времени выполнения. Он завершает выполнение программы, если происходит ошибка, связанная с системой или ресурсами (JVM).
Ошибки обычно представляют собой необычную проблему, после которой сложно произвести восстановление. Они происходят не по вине программиста, а из-за ненадлежащей работы системы или выделения ресурсов.
Примеры ошибок: AssertionError, LinkageError, OutOfMmeoryError, StackOverFlowError, VirtualMachineError.
Класс Exception представляет ошибки, вызванные программой или внешними факторами. Это надкласс для все классов исключений.
Для этого класса существует два конструктора:
Эти конструкторы наследуются всеми подклассами исключений. Сам по себе класс Exception не предоставляет собственных методов. Он наследует методы класса Throwable.
Встроенные исключения делятся на две группы: проверяемые (checked) и непроверяемые (unchecked).
Проверяемые исключения проверяются компилятором Java во время компиляции и не являются подклассами RuntimeException (исключения времени выполнения).
Если метод выбрасывает проверяемое исключение, то это исключение необходимо обработать либо в этом же методе, либо передать вызывающему методу.
Проверяемые исключения обрабатываются либо в блоке try-catch, либо в объявлении метода с ключевым словом throws. Если исключение не обработано, происходит ошибка компиляции.
Проверяемыми исключениями являются все исключения, кроме RuntimeException, Error и их подклассов.
Примеры проверяемых исключений: ClassNotFoundException, IOException, SQLException, IllegalAccessException, FileNotFoundException.
Непроверяемые исключения в Java – это исключения, которые проверяются JVM, а не компилятором Java. Они возникают во время выполнения программы.
Все подклассы RuntimeException называются непроверяемыми исключениями или исключениями времени выполнения в Java.
Можно написать программу на Java и скомпилировать ее, но мы не увидим непроверяемых исключений и ошибок, пока не запустим эту программу.
Компилятор Java не проверяет исключения времени выполнения во время компиляции, независимо от того, обрабатывает ли их программа.
Если в методе возникает исключение времени выполнения, а программист не обрабатывает его, JVM прекращает выполнение программы, не выполняя остаток кода.
Примеры непроверяемых исключений: ArithmeticException, ArrayIndexOutOfBoundsException, ClassCastException, NegativeArraySizeException, NullPointerException.
В Java определено множество встроенных исключений. Ниже приведены описания некоторых из них.
Исключение | Описание |
ArithmeticException | Выбрасывается, когда возникает исключительная арифметическая ситуация. |
ArrayIndexOutOfBoundsException | Выбрасывается при попытке обратиться к массиву по недействительному индексу. |
ArrayStoreException | Выбрасывается при попытке сохранить объект несоответствующего типа в массиве объектов. |
ClassCastException | Выбрасывается, когда код совершает попытку привести тип объекта к подклассу, экземпляром которого он не является. |
ClassNotFoundException | Выбрасывается, когда приложение совершает попытку загрузить класс по его имени в строковом представлении с использованием метода forName в классе Class. |
CloneNotSupportedException | Выбрасывается, когда для клонирования объекта определенного класса вызван метод clone, но класс этого объекта не реализует интерфейс Cloneable. |
EnumConstantNotPresentException | Выбрасывается, когда приложение производит попытку обратиться к константе из перечисления по имени, но тип этого перечисления не содержит константу с указанным именем. |
Exception | Класс Exception и его подклассы являются подклассами Throwable и указывают на ситуации, которые могут быть перехвачены приложением. |
IllegalAccessException | Выбрасывается, когда приложение совершает попытку применить рефлексию, чтобы создать экземпляр (отличный от массива), присвоить полю значение или получить значение поля, вызвать метод, но текущий выполняемый метод не имеет доступа к определению указанного класса, поля, метода или конструктора. |
IllegalArgumentException | Выбрасывается, когда методу передан недопустимый или неприемлемый аргумент. |
IllegalMonitorStateException | Выбрасывается, когда нить пытается ожидать монитор объекта или отправить оповещение другим нитям, ожидающим монитор объекта, но указанный монитор не принадлежит ей. |
IllegalStateException | Выбрасывается, когда метод вызван в недопустимое или неприемлемое время. |
IllegalThreadStateException | Выбрасывается, когда нить находится в неприемлемом состоянии для выполнения запрошенной операции. |
IndexOutOfBoundsException | Выбрасывается, когда индекс определенного типа (например, для массива, строки или вектора) находится вне допустимого диапазона. |
InstantiationException | Выбрасывается, когда приложение совершает попытку создать экземпляр класса с использованием метода newInstance класса Class, но создать экземпляр указанного класса невозможно. |
InterruptedException | Выбрасывается, когда нить находится в состоянии ожидания, сна или занята каким-либо другим образом, но ее работа прервана либо перед выполнением действия, либо после его выполнения. |
NegativeArraySizeException | Выбрасывается, когда приложение совершает попытку создать массив отрицательного размера. |
NoSuchFieldException | Выбрасывается, когда в классе отсутствует поле с указанным именем. |
NoSuchMethodException | Выбрасывается, когда невозможно найти указанный метод. |
NullPointerException | Выбрасывается, когда приложение совершает попытку использовать значение null, но требуется указать объект. |
NumberFormatException | Выбрасывается, когда приложение совершает попытку преобразовать строку в один из числовых типов, но строка имеет недопустимый формат. |
RuntimeException | Это родительский класс для тех исключений, которые могут быть выброшены при нормальной работе виртуальной машины Java. |
SecurityException | Выбрасывается менеджером безопасности при нарушении безопасности. |
StringIndexOutOfBoundsException | Выбрасывается методами класса String при попытке использовать отрицательный индекс или индекс, превышающий размер строки. |
TypeNotPresentException | Выбрасывается, когда приложение совершает попытку доступа к типу с указанием его имени в виде строки, но не удается найти определение типа с указанным именем. |
UnsupportedOperationException | Выбрасывается, когда запрошенная операция не поддерживается. |
Пользовательские исключения создаются пользователями или программистами в соответствии с их собственными потребностями. Они создаются путем расширения класса Exception.
Примером пользовательского исключения может служить исключение, выбрасываемое, если пользователь пытается открыть банковский счет, но не достиг возраста 18 лет. В таком случае может быть выдано сообщение о том, что требуется открыть счет с кем-то из родителей.
Чтобы использовать пользовательское исключение, нужно выполнить следующие действия.
Пример исключения с конструктором по умолчанию:
class MyException extends Exception{ // Конструктор по умолчанию MyException(){} } class Main{ public static void main(String[] args){ try{ MyException e = new MyException(); throw e; } catch(MyException ex){ System.out.println("Перехвачено пользовательское исключение"); } } }
Этот код выведет следующий текст: “Перехвачено пользовательское исключение”.
Пример исключения с параметром в конструкторе:
class MyException extends Exception{ MyException(String msg){ super(msg); } } class Main{ public static void main(String[] args){ try{ MyException e = new MyException("Перехвачено пользовательское исключение с информацией"); throw e; } catch(MyException ex){ System.out.println(ex.getMessage()); } } }
Вывод будет таким: “Перехвачено пользовательское исключение с информацией”
Исключения в Java позволяют указать пути обхода проблем и исправления их последствий. С их помощью можно поместить логику обработки исключительных ситуаций в отдельные блоки кода (catch), оставив основную логику в блоке try, а логику завершающих действий по обработке исключения – в блоке finally. Исключения могут быть обработаны в методах, где они возникают, или переданы далее с помощью ключевых throw и throws.
Java предоставляет обширный набор встроенных исключений, а также дает программисту гибкость, позволяя создавать собственные исключения в соответствии с потребностями приложения.
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…
Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…