Содержание
Исключение – это нежелательная ситуация, которая возникает во время выполнения программы и нарушает нормальный ход ее работы.
Такая ситуация может возникнуть, например, при попытке чтения из несуществующего файла, делении на ноль, сбое устройства и так далее. Исключение можно перехватить, чтобы принять соответствующие меры.
Приведем пример кода, в котором возникает исключение.
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 предоставляет обширный набор встроенных исключений, а также дает программисту гибкость, позволяя создавать собственные исключения в соответствии с потребностями приложения.
На фоне роста спроса на ликвидность в бычьем рынке 2025 года, криптозаймы снова выходят на…
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…