Uncaughtexceptionhandler java что это
Перехват необрабатываемых исключений
В статье от 16 марта 2004 года Best Practices in Exception Handling были описаны приемы обработки исключений. В данной статье вы изучите новый способ обработки исключений при помощи класса UncaughtExceptionHandler добавленного в J2SE 5.0.
Как можно понять из названия класса UncaughtExceptionHandler, он предназначен для перехвата необрабатываемых исключений. Более точно, он предназначен для перехвата необрабатываемых исключений времени исполнения. Java компилятор требует обработки всех исключений, не относящихся к исключениям времени исполнения, иначе программа не будет откомпилирована. Здесь термин обработка подразумевает то, что исключения объявлены при помощи слова throws при объявлении метода или же перехвачены при помощи оператора catch в блоке try-catch.
Для демонстрации вышеприведенных утверждений давайте рассмотрим два исключения: FileNotFoundException и ArithmeticException. При вызове конструктора FileReader с аргументом типа String или File будет выброшено исключение FileNotFoundException в случае если данный аргумент не указывает на файл. Компилятор требует, чтобы при вызове данного конструктора вы обрабатывали выбрасываемое исключение.
В сравнении с предыдущим исключением, исключение ArithmeticException относится к исключениям времени исполнения. Спецификация языка программирования Java (а также и компилятор) не требует обработки исключений времени исполнения. Таким образом, следующий цикл делящий 100 на числа от 10 до 0, выбросит исключение ArithmeticException во время последнего прохождения цикла.
for ( int i= 10 ; i >= 0 ; i— ) <
int div = 100 / i;
>
Exception in thread «main» java.lang.ArithmeticException: / by zero at Test.main ( Test.java: 4 )
По умолчанию обработчик необрабатываемых ошибок выводит содержимое стека. Обычно, данное поведение по умолчанию является достаточным, но бывают случаи, когда его не достаточно. Представьте, что вы хотите отображать содержимое стека во всплывающем окне, вместо печати его в системной консоли. Установив свой обработчик необрабатываемых ошибок, вы можете получить данное поведение.
Существует три способа установки обработчика необрабатываемых ошибок. Первое, вы можете вызвать метод setUncaughtExceptionHandler() класса Thread.. Его вызов позволяет настроить поведение обработчика для выбранного потока. Второе, вы можете создать объект ThreadGroup и изменять поведение всех потоков в группе переопределив метод uncaughtException(). Третье, вы можете установить поведение по умолчанию для всех потоков вызвав статический метод setDefaultUncaughtExceptionHandler() класса Thread.
Методы setUncaughtExceptionHandler() и setDefaultUncaughtExceptionHandler() класса Thread в качестве аргумента принимает реализацию интерфейса UncaughtExceptionHandler. Данный интерфейс является внутренним интерфейсом класса Thread, таким образом, его полное имя будет Thread.UncaughtExceptionHandler. В данном интерфейсе определен один метод:
Вы можете создать свое поведение создав реализацию метода uncaughtException, либо как реализацию интерфейса, либо переопределив метод класса ThreadGroup. Для примера, мы создадим реализацию UncaughtExceptionHandler, которая отображает окно с содержимым стека, в текстовом поле при возникновении ошибки времени исполнения. Вы можете закрывать окно в промежутках возникновения ошибок. Окно вновь появится при следующем возникновении ошибки.
import java.awt.*;
import java.io.*;
import javax.swing.*;
public class StackWindow extends JFrame
implements Thread.UncaughtExceptionHandler <
private JTextArea textArea;
public void uncaughtException ( Thread t, Throwable e ) <
addStackInfo ( e ) ;
>
public void addStackInfo ( final Throwable t ) <
EventQueue.invokeLater ( new Runnable () <
public void run () <
setVisible ( true ) ;
toFront () ;
StringWriter sw = new StringWriter () ;
PrintWriter out = new PrintWriter ( sw ) ;
t.printStackTrace ( out ) ;
textArea.append ( sw.toString ()) ;
>
>) ;
>
>
Для теста обработчика вам необходима программа, устанавливающая обработчик и затем выбрасывающая несколько ошибок времени исполнения. Нижеприведенная программа DumpTest, выполняет данные требования. Вы можете добавить свой корд в программу, который будет выбрасывать другие ошибки. Программа приостанавливает выполнение между ошибками, чтобы показать вам, что вы можете закрывать окно с сообщением об ошибках.
Скомпилируйте классы StackWindow и DumpTest. При запуске DumpTest в консоли вы увидите следующие строки:
Так же вы увидите окно с сообщением об ошибке в текстовом поле.
Нажмите Enter и вы увидите следующее сообщение в консоли:
Вы также увидите второе сообщение ошибке в текстовом поле окна.
Хотя вам может показаться, что данный материал покрывает все возможности по обработке ошибок, на самом деле это не так. Модальные диалоги требуют своего собственного потока событий и поэтому своего обработчика. Системное свойство sun.awt.exception.handler обладает всеми необходимыми классами, но оно плохо документировано. Был опубликован запрос на расширение данного свойства в формальный API.
Uncaughtexceptionhandler java что это
В основном, код, который может вызвать исключение помещается в такую конструкцию. Блок catch описываемый для определенного исключения будет вызываться – т.е. если случится исключение TheException1, тогда будет вызван блок внутри его catch. Однако блок finally будет вызываться всегда, даже если какой-либо блок catch содержит return.
Таким образом думаю понятно, что блок try должен быть всегда. И всегда должен быть хотя бы один из блоков catch или finally.
Исходя из того, что блоков catch может быть много, система в случае исключения будет искать первый подходящий тип исключения. Причем с учетом наследования. Т.е. если вы ловите исключение IOException, то исключение FileNotFoundException, которрое является подклассом IOException будет обрабатываться в блоке try, который содержит IOException. Думаю, что это несложно.
Первый совет по обработке исключений: старайтесь обрабатывать специфические исключения. Т.е. если вы создали метод, который будет генерировать исключение FileNotFoundException – не декларируйте, что метод взывает исключение IOException. Нехорошо заставлять пользователя вашим классом обрабатывать исключение более высокого уровня, чем надо в действительности.
Второй совет: не делайте пустых catch блоков. Иными словами не делйте такой код.
Если даже логика вашего кода подразумевает полное отсуствие каких-либо действий при исключении – не поленитесь и напишите комментарий. Иначе пользватели вашего кода будут в затруднении.
Еще один добрый совет: Если метод класса вызывает исключение – пишите на него документацию. Используйте тэг @throws.
Наверняка вы знаете о RuntimeException и его подклассах. Эти исключения не требуют, чтобы их обрабатывали. И в общем не всегда их обработка будет выглядет логичной и нужной.
Но в некоторых случаях это будет логично и понятно. Например если вы ожидаете от пользователя ввода целого числа, которе вводится как строка. Для преобразования скорее всего будет использован методв parseInt, который вызывает runtime исключение NumberFormatException. Обычно runtime исключения обрабатываются тогда, когда необходимо восстановление при таких исключениях. Как в выше приведенном примере с parseInt.
Новые возможности Java 1.5 – UncaughtExceptionHandler
Мы уже говорили о том, что есть non-runtime исключения, которые вы обязаны помещать в блок try/catch и runtime, которые не требуют специальной обработки. Но бывают случаи, когда требуется обрабатывать и их – например вы хотите выводить все сообщения в определенном формате в какое-то окно сообщений. Расставлять по всему коду блоки try/catch конечно не очень удобное занятие.
Существуют три способа сделать обработку runtime исключений.
Вызвать метод setUncaughtExceptionHandler() у класса Thread.
Определить свой класс ThreadGroup и переопределить метод uncaughtException().
Вызвать статический метод класса Thread — setDefaultUncaughtExceptionHandler().
Методы setUncaughtExceptionHandler() и setDefaultUncaughtExceptionHandler() принимают в качестве аргумента класс, который реализует интерфейс UncaughtExceptionHandler.
Этот интерфейс имеет всего один метод
void uncaughtException(Thread t, Throwable e)
Рассмотрим в качестве примера два класса.
Первый класс представляет из себя окно, которое будет «всплывать» при возникновении исключнения. Окно реализует интерфейс UncaughtExceptionHandler.
Надо обратить внимание на два момента:
1. Это метод uncaughtException. Он реализует интерфейс
2. Метод addStackInfo. В общем-то в нем и происхожит основная работа.
Чтобы вы не пугались — EventQueue.invokeLater представляет из себя метод, который вызывается «в очереди» и что важно отметить делается асинхронно (в отдельном треде).
Все остальные вызовы достаточно очевидны – сделать окно видимым, вывести его на передний план, создать два потока для печати строк и вывести строки. В общем-то и все.
Uncaughtexceptionhandler java что это
When a thread is about to terminate due to an uncaught exception the Java Virtual Machine will query the thread for its UncaughtExceptionHandler using Thread.getUncaughtExceptionHandler() and will invoke the handler’s uncaughtException method, passing the thread and the exception as arguments. If a thread has not had its UncaughtExceptionHandler explicitly set, then its ThreadGroup object acts as its UncaughtExceptionHandler. If the ThreadGroup object has no special requirements for dealing with the exception, it can forward the invocation to the default uncaught exception handler.
Method Summary
Modifier and Type | Method and Description |
---|---|
void | uncaughtException(Thread t, Throwable e) |
Method Detail
uncaughtException
Any exception thrown by this method will be ignored by the Java Virtual Machine.
Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2020, Oracle and/or its affiliates. All rights reserved. Use is subject to license terms. Also see the documentation redistribution policy.
Обработка ошибок и исключения
Содержание
Методы обработки ошибок [ править ]
2. Коды возврата. Основная идея — в случае ошибки возвращать специальное значение, которое не может быть корректным. Например, если в методе есть операция деления, то придется проверять делитель на равенство нулю. Также проверим корректность аргументов a и b :
При вызове метода необходимо проверить возвращаемое значение:
Минусом такого подхода является необходимость проверки возвращаемого значения каждый раз при вызове метода. Кроме того, не всегда возможно определить тип ошибки.
3.Использовать флаг ошибки: при возникновении ошибки устанавливать флаг в соответствующее значение:
Минусы такого подхода аналогичны минусам использования кодов возврата.
4.Можно вызвать метод обработки ошибки и возвращать то, что вернет этот метод.
Но в таком случае не всегда возможно проверить корректность результата вызова основного метода.
5.В случае ошибки просто закрыть программу.
Это приведет к потере данных, также невозможно понять, в каком месте возникла ошибка.
Исключения [ править ]
В Java возможна обработка ошибок с помощью исключений:
Каждый раз, когда при выполнении программы происходит ошибка, создается объект-исключение, содержащий информацию об ошибке, включая её тип и состояние программы на момент возникновения ошибки. После создания исключения среда выполнения пытается найти в стеке вызовов метод, который содержит код, обрабатывающий это исключение. Поиск начинается с метода, в котором произошла ошибка, и проходит через стек в обратном порядке вызова методов. Если не было найдено ни одного подходящего обработчика, выполнение программы завершается.
Таким образом, механизм обработки исключений содержит следующие операции:
Классификация исключений [ править ]
Проверяемые исключения [ править ]
Наследники класса Exception (кроме наслеников RuntimeException ) являются проверяемыми исключениями(checked exception). Как правило, это ошибки, возникшие по вине внешних обстоятельств или пользователя приложения – неправильно указали имя файла, например. Эти исключения должны обрабатываться в ходе работы программы, поэтому компилятор проверяет наличие обработчика или явного описания тех типов исключений, которые могут быть сгенерированы некоторым методом.
Все исключения, кроме классов Error и RuntimeException и их наследников, являются проверяемыми.
Error [ править ]
Класс Error и его подклассы предназначены для системных ошибок. Свои собственные классы-наследники для Error писать (за очень редкими исключениями) не нужно. Как правило, это действительно фатальные ошибки, пытаться обработать которые довольно бессмысленно (например OutOfMemoryError ).
RuntimeException [ править ]
Обработка исключений [ править ]
Как и было сказано раньше, определение метода должно содержать список всех проверяемых исключений, которые метод может бросить. Также можно написать более общий класс, среди наследников которого есть эти исключения.
try-catch-finally [ править ]
Сразу после блока проверки следуют обработчики исключений, которые объявляются ключевым словом catch.
Обработка исключений, вызвавших завершение потока [ править ]
Информация об исключениях [ править ]
Разработка исключений [ править ]
Исключения в Java7 [ править ]
Можно объявлять несколько ресурсов, разделяя их точкой с запятой:
Компилятор Java SE 7 тщательнее анализирует перебрасываемые исключения. Рассмотрим следующий пример:
Примеры исключений [ править ]
Гарантии безопасности [ править ]
При возникновении исключительной ситуации, состояния объектов и программы могут удовлетворять некоторым условиям, которые определяются различными типами гарантий безопасности:
Если будет брошено исключение в этом классе, то тогда гарантируется, что ивариант «левая граница интервала меньше правой» сохранится, но значения left и right могли измениться.
Блог только про Java
Учимся программировать на Java с нуля
Обработчик неперехваченных исключений Java
Метод run() потока не может генерировать никаких контролируемых исключений, но может быть прерван неконтролируемым исключением. В этом случае поток уничтожается.
Однако нет конструкции catch, куда может распространиться исключение. Вместо этого непосредственно перед смертью потока исключение передается обработчику неперехваченных исключений. Обработчик должен относиться к классу, реализующему интерфейс Thread.UncaughtExceptionHandler. Этот интерфейс имеет единственный метод:
Начиная с Java SE 5.0, вы можете инсталлировать обработчик в любой поток методом setUncaughtExceptionHandler.
Вы можете также инсталлировать обработчик по умолчанию для всех потоков с помощью статического метода setDefaultUncaughtExceptionHandler() класса Thread.
Заменяющий обработчик может использовать API протоколирования для отправки отчетов о необработанных исключениях в файл протокола.
Если вы не инсталлируете обработчик по умолчанию, то им является null. Однако если вы не инсталлируете обработчик для индивидуального потока, то обработчиком является объект потока ThreadGroup.