В языке Java желательно сообщать программисту, вызывающему ваш метод, об исключениях, которые данный метод способен возбуждать. Пользователь, вызывающий метод, сможет написать весь необходимый код для перехвата возможных исключений. Конечно, когда доступен исходный код, программист-клиент может пролистать его в поиске предложений throw, но библиотеки не всегда поставляются с исходными текстами. Чтобы библиотека не превращалась в «черный ящик», в Java добавили синтаксис (
Спецификация исключений состоит из ключевого слова throws, за которым перечисляются все возможные типы исключений. Примерное определение метода будет выглядеть так:
void f() throws TooBig. TooSmall. DivZero { //...
Однако запись
void f() { // ...
означает, что метод не вырабатывает исключений. (
Обойти спецификацию исключений невозможно — если ваш метод возбуждает исключения и не обрабатывает их, компилятор предложит либо обработать исключение, либо включить его в спецификацию. Жестким контролем за соблюдением правил сверху донизу Java гарантирует правильность использования механизма исключений во время компиляции программы.
Впрочем, «обмануть» компилятор все же можно: вы вправе объявить о возбуждении исключения, которого на самом деле нет. Компилятор верит вам на слово и заставляет пользователей метода поступать так, как будто им и в самом деле необходимо перехватывать исключение. Таким образом можно «зарезервировать» исключение на будущее и уже потом возбуждать его, не изменяя описания готовой программы. Такая возможность может пригодиться и для создания абстрактных базовых классов и интерфейсов, в производных классах которых может возникнуть необходимость в возбуждении исключений.
Исключения, которые проверяются и навязываются еще на этапе компиляции программы, называют
Перехват произвольных исключений
Можно создать универсальный обработчик, перехватывающий любые типы исключения. Осуществляется это перехватом базового класса всех исключений Exception (существуют и другие базовые типы исключений, но класс Exception является базовым практически для всех программных исключительных ситуаций):
catch(Exception е) {
System.out рппШСПерехвачено исключение");
}
Подобная конструкция не упустит ни одного исключения, поэтому ее следует размещать в самом конце списка обработчиков, во избежание блокировки следующих за ней обработчиков исключений.
Поскольку класс Exception является базовым для всех классов исключений, интересных программисту, сам он не предоставит никакой полезной информации об исключительной ситуации, но можно вызвать методы из
• String getMessage(), String getLocalizedMessage() возвращают подробное сообщение об ошибке (или сообщение, локализованное для текущего контекста);
• String toString() возвращает короткое описание объекта Throwable, включая подробное сообщение, если оно присутствует;
• void printStackTrace(), void printStackTrace(PrintStream), void printStack-Trace(java.io.PrintWriter) выводят информацию об объекте Throwable и трассировку стека вызовов для этого объекта. Трассировка стека вызовов показывает последовательность вызова методов, которая привела к точке возникновения исключения. Первый вариант отправляет информацию в стандартный поток ошибок, второй и третий — в поток по
вашему выбору (в главе «Ввод/вывод» вы поймете, почему типов потоков два);
• Throwable fiUInStackTrace() записывает в объект Throwable информацию о текущем состоянии стека. Метод используется при повторном возбуждении ошибок или исключений.
Вдобавок в вашем распоряжении находятся методы типа Object, базового для Throwable (и для всех остальных классов). При использовании исключений может пригодиться метод getClass(), который возвращает информацию о классе объекта. Эта информация заключена в объекте типа Class. Например, вы можете узнать имя класса вместе с информацией о пакете методом getName() или получить только имя класса методом getSimpleName().
Рассмотрим пример с использованием основных методов класса Exception:
//. exceptions/ExceptionMethods.java // Демонстрация методов класса Exception, import static net.mindview.util.Print.*;
public class ExceptionMethods {
public static void main(String[] args) { try {
throw new Exception("Мое исключение"); } catch(Exception e) {
print("Перехвачено"). print("getMessage():" + e.getMessageO); print("getLocalizedMessage()." +
e.getLocali zedMessage());
print ("toStringO." + e); print("printStackTrace():"); e.printStackTrace(System.out);
}
}
} /* Output. Перехвачено
getMessageO :Moe исключение