Исключение в программировании - это возникновение ошибок и непредвиденных ситуаций при выполнении программы.
Исключения (ошибки при выполнении программы) могут возникать в результате:
- неправильных действий пользователя
- отсутствии необходимого ресурса на диске
- потери соединения с сервером по сети
- ошибки программирования
- неправильное использование API.
Настраивают управление исключениями для того, чтобы программа чётко знала, как поступать в ситуации появления ошибок при выполнении программы.
(чтобы предупредить и решить исключительные ситуации в программе, для того чтобы её выполнение могло быть продолжено)
В частности, механизм исключений позволяет защитить написанный код (программный интерфейс) от неправильного использования пользователем за счет валидации (проверки) входящих данных.
Использование исключений в Java позволяет повысить отказоустойчивость программы за счет использования «запасных» путей, отделить логику основного кода от кода обработки исключительных ситуаций за счет использования блоков catch, а также дает возможность переложить обработку исключений на пользователя нашего кода с помощью throws.
Обработка исключений в Java основана на использовании в программе следующих ключевых слов
try, catch, finally, throws
1) try – определяет (заключает под собой) блок кода, в котором может произойти исключение;
2) catch – определяет (заключает под собой) блок кода, в котором происходит обработка исключения;
(Действия при сбое, который может случиться внутри оператора try)
3) finally – определяет (заключает под собой) блок кода, который является необязательным, но при его наличии выполняется в любом случае независимо от результатов выполнения блока try.
(Блок finally часто используется для того, чтобы закрыть открытые в блоке try потоки или освободить ресурсы. Однако при написании программы не всегда возможно уследить за закрытием всех ресурсов. Для облегчения этой задачи существует конструкция try-with-resources, которая автоматически закрывает ресурсы, открытые в блоке try).
Эти ключевые слова используются для создания в программном коде специальных обрабатывающих конструкций: try{}catch, try{}catch{}finally, try{}finally{}.
На стадии разработки программы мы «ограждаем» опасные участки кода в отношении исключений с помощью блока try{}, предусматриваем «запасные» пути с помощью блока catch{}, в блоке finally{} мы пишем код, который выполняется в программе при любом исходе.
При появлении исключения в блоке try обработчик исключения ищется в следующем за ним блоке catch. Если в catch есть обработчик данного типа исключения – управление переходит к нему. Если нет, то JVM ищет обработчик этого типа исключения в цепочке вызовов методов до тех пор, пока не будет найден подходящий catch. После выполнения блока catch управление передается в необязательный блок finally. В случае, если подходящий блок catch не найден, JVM останавливает выполнение программы, и выводит стек вызовов методов – stack trace, выполнив перед этим код блока finally при его наличии.
Переменные, определенные в try не могут быть использованы в catch или finally, этот код не скомпилируется. Причина в том, что неизвестно, где именно в блоке try могло быть вызвано исключение, например, возможно, что исключение было вызвано до того, как был объявлен объект.
4) throw – используется для возбуждения исключения
5) throws – Это ключевое слово в сигнатуре метода означает, что при определенных условиях метод, может выбросить исключение
(Ключевое слово throws используется когда не планируется обрабатывать исключение в своем методе, но необходимо предупредить пользователей метода о возможных исключительных ситуациях)
Такое предупреждение является частью интерфейса метода и предоставляет право пользователю на собственный вариант реализации обработчика исключения (предоставляя написание кода по обработке исключения в Java пользователю метода.).
После throws указывается тип выбрасываемого исключения.
Типы выбрасываемых исключений:
Обычно это наследники класса Exception Java.
Поскольку Java является объектно-ориентированным языком, все исключения в Java представляют собой объекты.
При возникновении ошибки в процессе выполнения программы исполняющая
среда JVM создает объект нужного типа из иерархии исключений Java.
Иерархия исключений java:
Throwable - название класса "предка", от которого унаследовано множество возможных исключительных ситуаций.
Далее всё это множество исключительных ситуаций можно разделить на две группы:
1) Непроверяемые на стадии компиляции (неконтролируемые) (unchecked)
Это Error (исключения, унаследованные из класса Error) + RuntimeException (часть исключений - наследников класса Exception)
RuntimeException – исключения, генерируемые JVM во время выполнения программы. Часто
причиной возникновения их являются ошибки программирования.
К этой группе относятся ситуации, при которых восстановление дальнейшей нормальной работы программы невозможно.
Это ошибки, возникающие при выполнении программы в результате сбоя работы JVM, переполнения памяти или сбоя системы. Обычно они свидетельствуют о серьезных проблемах, устранить которые программными средствами невозможно, такими как деление на 0, нулевой указатель и т.п.
Список непроверяемых исключений:
ArithmeticException - арифметическая ошибка, например, деление на ноль
ArrayIndexOutOfBoundsException - выход индекса за границу массива
ArrayStoreException - присваивание элементу массива объекта несовместимого типа
ClassCastException - неверное приведение
EnumConstantNotPresentException - попытка использования неопределённого значения перечисления
IllegalArgumentException - неверный аргумент при вызове метода
IllegalMonitorStateException - неверная операция мониторинга
IllegalStateException - некорректное состояние приложения
IllegalThreadStateException - запрашиваемая операция несовместима с текущим потоком
IndexOutofBoundsException - тип индекса вышел за допустимые пределы
NegativeArraySizeException - создан массив отрицательного размера
NullPointerException - неверное использование пустой ссылки
NullPointerException (оно же NPE) - это исключение, которое
выбрасывается каждый раз, когда вы обращаетесь к методу или полю объекта
по ссылке, которая равна null.
NumberFormatException - неверное преобразование строки в числовой формат SecurityException - попытка нарушения безопасности
StringIndexOutOfBounds - попытка использования индекса за пределами строки
TypeNotPresentException - тип не найден
UnsupportedOperationException - обнаружена неподдерживаемая операция
2) Проверяемые на стадии компиляции (предвидимые еще на стадии написания программы) (контролируемые) (checked)
Это Exception (кроме RuntimeException)
Основная часть работы разработчика на Java при работе с исключениями – обработка таких ситуаций: проверяемые исключения должны быть явно пойманы в теле метода или объявлены в секции throws метода.
Для проверяемых исключений ожидается, что другие разработчики, использующие API, будут знать,
как обращаться с исключениями.
Список проверяемых системных исключений, которые можно включать в список throws:
ClassNotFoundException - класс не найден
CloneNotSupportedException - попытка клонировать объект, который не реализует интерфейс Cloneable
IllegalAccessException - запрещен доступ к классу
InstantiationException - попытка создать объект абстрактного класса или интерфейса
InterruptedException - поток прерван другим потоком
NoSuchFieldException - запрашиваемое поле не существует
NoSuchMethodException - запрашиваемый метод не существует
ReflectiveOperationException - исключение, связанное с рефлексией
Пример использования ключевых слов в java-программе:
//метод считывает строку с клавиатуры
public String input() throws MyException {//предупреждаем с помощью throws,
// что метод может выбросить исключение MyException
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String s = null;
//в блок try заключаем код, в котором может произойти исключение, в данном
// случае компилятор нам подсказывает, что метод readLine() класса
// BufferedReader может выбросить исключение ввода/вывода
try {
s = reader.readLine();
// в блок catch заключаем код по обработке исключения IOException
} catch (IOException e) {
System.out.println(e.getMessage());
// в блоке finally закрываем поток чтения
} finally {
// при закрытии потока тоже возможно исключение, например, если он не был открыт, поэтому “оборачиваем” код в блок try
try {
reader.close();
// пишем обработку исключения при закрытии потока чтения
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
if (s.equals("")) {
// мы решили, что пустая строка может нарушить в дальнейшем работу нашей программы, например, на результате этого метода нам надо вызывать метод substring(1,2), поэтому мы вынуждены прервать выполнение программы с генерацией своего типа исключения MyException с помощью throw
throw new MyException("String can not be empty!");
}
return s;
}
Этот же пример с помощью try-with-resources
:
public String input() throws MyException {
String s = null;
try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))){
s = reader.readLine();
} catch (IOException e) {
System.out.println(e.getMessage());
}
if (s.equals("")){
throw new MyException ("String can not be empty!");
}
return s;
}
Комментариев нет:
Отправить комментарий