1. Введение
В этом руководстве рассматриваются некоторые распространенные исключения Java.
Мы начнем с обсуждения того, что такое исключение. Позже мы подробно обсудим различные типы проверенных и непроверенных исключений.
2. Исключения
Исключение — это ненормальное состояние, возникающее в последовательности кода во время выполнения программы. Это ненормальное состояние возникает, когда программа нарушает определенные ограничения во время выполнения.
Все типы исключений являются подклассами класса Exception
. Затем этот класс подразделяется на проверенные исключения и непроверенные исключения. Мы подробно рассмотрим их в следующих разделах.
3. Проверенные исключения
Отмеченные исключения являются обязательными для обработки. Они являются прямыми подклассами класса Exception
.
Об их важности ведутся споры , на которые стоит обратить внимание.
Давайте подробно определим некоторые проверяемые исключения.
3.1. IOException
Метод генерирует исключение IOException
или его прямой подкласс при сбое любой операции ввода/вывода. ``
Типичные варианты использования этих операций ввода/вывода включают:
- Работа с файловой системой или потоками данных с использованием пакета
java.io
- Создание сетевых приложений с использованием пакета
java.net
FileNotFoundException
FileNotFoundException
— распространенный тип IOException
при работе с файловой системой:
try {
new FileReader(new File("/invalid/file/location"));
} catch (FileNotFoundException e) {
LOGGER.info("FileNotFoundException caught!");
}
MalformedURLException
При работе с URL-адресами мы можем столкнуться с MalformedURLException —
если наши URL-адреса недействительны.
try {
new URL("malformedurl");
} catch (MalformedURLException e) {
LOGGER.error("MalformedURLException caught!");
}
3.2. ParseException
Java использует синтаксический анализ текста для создания объекта на основе заданной строки.
Если синтаксический анализ вызывает ошибку, он выдает ParseException
.
Например, мы можем представить дату
по-разному, например , дд/мм/гггг
или дд, мм, гггг,
но попробуем разобрать строку
в другом формате:
try {
new SimpleDateFormat("MM, dd, yyyy").parse("invalid-date");
} catch (ParseException e) {
LOGGER.error("ParseException caught!");
}
Здесь строка
имеет неверный формат и вызывает ParseException
.
3.3. InterruptedException
Всякий раз, когда поток Java вызывает функцию join(), sleep()
или wait()
, он переходит либо в состояние WAITING , либо в состояние
TIMED_WAITING
.
Кроме того, поток может прервать другой поток, вызвав метод прерывания() другого потока.
Следовательно, поток генерирует InterruptedException
, если другой поток прерывает его, пока он находится в состоянии WAITING
или TIMED_WAITING
.
Рассмотрим следующий пример с двумя потоками:
- Основной поток запускает дочерний поток и прерывает его.
- Запускается дочерний поток и вызывается
sleep()
Этот сценарий приводит к InterruptedException:
class ChildThread extends Thread {
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
LOGGER.error("InterruptedException caught!");
}
}
}
public class MainThread {
public static void main(String[] args)
throws InterruptedException {
ChildThread childThread = new ChildThread();
childThread.start();
childThread.interrupt();
}
}
4. Непроверенные исключения
Для непроверенных исключений компилятор не проверяет их в процессе компиляции. Следовательно, методу не обязательно обрабатывать эти исключения.
Все непроверенные исключения расширяют класс RuntimeException.
Давайте подробно обсудим некоторые непроверенные исключения.
4.1. Исключение нулевого указателя
Если приложение попытается использовать null
там, где ему на самом деле требуется экземпляр объекта, метод выдаст исключение NullPointerException
.
Существуют различные сценарии, в которых незаконное использование нулевого значения
вызывает исключение NullPointerException.
Рассмотрим некоторые из них.
Вызов метода класса, не имеющего экземпляра объекта:
String strObj = null;
strObj.equals("Hello World"); // throws NullPointerException.
Кроме того, если приложение попытается получить доступ или изменить переменную экземпляра с нулевой
ссылкой, мы получим исключение NullPointerException:
Person personObj = null;
String name = personObj.personName; // Accessing the field of a null object
personObj.personName = "Jon Doe"; // Modifying the field of a null object
4.2. ArrayIndexOutOfBoundsException
Массив хранит свои элементы в непрерывном порядке. Таким образом, мы можем получить доступ к его элементам через индексы.
Однако , если фрагмент кода пытается получить доступ к недопустимому индексу массива, соответствующий метод выдает исключение ArrayIndexOutOfBoundException.
Давайте посмотрим на несколько примеров, которые вызывают ArrayIndexOutOfBoundException
:
int[] nums = new int[] {1, 2, 3};
int numFromNegativeIndex = nums[-1]; // Trying to access at negative index
int numFromGreaterIndex = nums[4]; // Trying to access at greater index
int numFromLengthIndex = nums[3]; // Trying to access at index equal to size of the array
4.3. StringIndexOutOfBoundsException
Класс String
в Java предоставляет методы для доступа к определенному символу строки или для выделения массива символов из строки.
Когда мы используем эти методы, внутри он преобразует строку
в массив символов.
Опять же, в этом массиве может иметь место незаконное использование индексов. В таких случаях эти методы класса String
вызывают исключение StringIndexOutOfBoundsException
.
Это исключение указывает, что индекс больше или равен размеру строки.
StringIndexOutOfBoundsException
расширяет IndexOutOfBoundsException
.
Метод charAt(index)
класса String
выдает это исключение, когда мы пытаемся получить доступ к символу по индексу, равному длине строки,
или какому-то другому недопустимому индексу:
String str = "Hello World";
char charAtNegativeIndex = str.charAt(-1); // Trying to access at negative index
char charAtLengthIndex = str.charAt(11); // Trying to access at index equal to size of the string
4.4. NumberFormatException
Довольно часто приложение заканчивается числовыми данными в String
. Чтобы интерпретировать эти данные как числовые, Java позволяет преобразовывать String
в числовые типы. Классы-оболочки, такие как Integer, Float и т. д.,
содержат служебные методы для этой цели.
Однако, если String
не имеет соответствующего формата во время преобразования, метод создает исключение NumberFormatException.
Рассмотрим следующий фрагмент.
Здесь мы объявляем строку
с буквенно-цифровыми данными. Далее мы пытаемся использовать методы класса- обертки Integer
для интерпретации этих данных как числовых.
Следовательно, это приводит к NumberFormatException:
String str = "100ABCD";
int x = Integer.parseInt(str); // Throws NumberFormatException
int y = Integer.valueOf(str); //Throws NumberFormatException
4.5. Арифметическое исключение
Когда программа вычисляет арифметическую операцию и в результате возникает какое-то исключительное состояние, она выдает ArithmeticException
. Кроме того, ArithmeticException
применяется только к типам данных int
и long .
Например, если мы попытаемся разделить целое число на ноль, мы получим исключение ArithmeticException
:
int illegalOperation = 30/0; // Throws ArithmeticException
4.6. ClassCastException
Java допускает приведение типов между объектами для поддержки наследования и полиморфизма. Мы можем либо повышать объект, либо понижать его.
При восходящем приведении мы приводим объект к его супертипу. А при понижении мы приводим объект к одному из его подтипов.
Однако во время выполнения, если код пытается преобразовать объект в подтип, экземпляром которого он не является, метод генерирует исключение ClassCastException
.
Экземпляр среды выполнения — это то, что действительно важно при приведении типов. Рассмотрим следующее наследование между Animal
, Dog и Lion
:
class Animal {}
class Dog extends Animal {}
class Lion extends Animal {}
Далее, в классе драйвера мы приводим ссылку Animal
, содержащую экземпляр Lion
, к Dog
.
Однако во время выполнения JVM замечает, что экземпляр Lion
несовместим с подтипом класса Dog
.
Это приводит к ClassCastException:
Animal animal = new Lion(); // At runtime the instance is Lion
Dog tommy = (Dog) animal; // Throws ClassCastException
4.7. IllegalArgumentException
Метод генерирует исключение IllegalArgumentException
, если мы вызываем его с некоторыми недопустимыми или неподходящими аргументами.
Например, метод sleep()
класса Thread
ожидает положительное время, и мы передаем отрицательный интервал времени в качестве аргумента. Это приводит к IllegalArgumentException
:
Thread.currentThread().sleep(-10000); // Throws IllegalArgumentException
4.8. Илегалстатеексцептион
IllegalStateException
сигнализирует о том, что метод был вызван в недопустимое или неподходящее время.
Каждый объект Java имеет состояние (переменные экземпляра) и некоторое поведение (методы). Таким образом, IllegalStateException
означает, что недопустимо вызывать поведение этого объекта с текущими переменными состояния.
Однако с некоторыми другими переменными состояния это может быть допустимо.
Например, мы используем итератор для итерации списка. Всякий раз, когда мы инициализируем его, он внутренне устанавливает свою переменную состояния lastRet
в -1.
В этом контексте программа пытается вызвать метод удаления
в списке:
//Initialized with index at -1
Iterator<Integer> intListIterator = new ArrayList<>().iterator();
intListIterator.remove(); // IllegalStateException
Внутри метод удаления
проверяет переменную состояния lastRet
и, если она меньше 0, генерирует исключение IllegalStateException.
Здесь переменная по-прежнему указывает на значение -1.
В результате мы получаем IllegalStateException
.
5. Вывод
В этой статье мы впервые обсудили, что такое исключения. Исключением является событие
, происходящее во время выполнения программы, которое нарушает нормальный ход инструкций программы.
Затем мы разделили исключения на проверенные исключения и непроверенные исключения.
Далее мы обсудили различные типы исключений, которые могут возникнуть во время компиляции или во время выполнения.
Мы можем найти код этой статьи на GitHub .