Исторически сложилось, что программисты, использующие операционные системы с поддержкой возобновления, со временем переходили к модели прерывания, забывая другую модель. Хотя идея возобновления выглядит привлекательно, она не настолько полезна на практике. Основная причина кроется в
Создание собственных исключений
Ваш выбор не ограничивается использованием уже существующих в Java исключений. Иерархия исключений JDK не может предусмотреть все возможные ошибки, поэтому вы вправе создавать собственные типы исключений для обозначения специфических ошибок вашей программы.
Для создания собственного класса исключения вам придется определить его производным от уже существующего типа — желательно наиболее близкого к вашей ситуации (хоть это и не всегда возможно). В простейшем случае создается класс с конструктором по умолчанию:
//• exceptions/InheritingExceptions java
// Создание собственного исключения
class SimpleException extends Exception {}
public class InheritingExceptions {
public void f() throws SimpleException {
System.out.printin("Возбуждаем SimpleException из f()"). throw new SimpleException();
}
public static void main(String[] args) {
Inherit! ngExcepti ons sed = new InheritingExceptionsO;
try {
sed.fO; } catch(SimpleException e) {
System.out.println( Перехвачено!").
}
}
} /* Output
Возбуждаем SimpleException из f() Перехвачено! */// ~
Компилятор создает конструктор по умолчанию, который автоматически вызывает конструктор базового класса. Конечно, в этом случае вы лишаетесь конструктора вида SimpleException(String), но на практике он не слишком часто используется. Как вы еще увидите, наиболее важно в исключении именно имя класса, так что в основном исключений, похожих на созданное выше, будет достаточно.
В примере результаты работы выводятся на консоль. Впрочем, их также можно направить в стандартный поток ошибок, что достигается использованием класса System.err. Обычно это правильнее, чем выводить в поток System.out, который может быть перенаправлен. При выводе результатов с помощью System, err пользователь заметит их скорее, чем при выводе в System.out.
Также можно создать класс исключения с конструктором, получающим аргумент String:
//: exceptions/Full Constructors java
class MyException extends Exception { public MyException() {}
public MyException(String msg) { super(msg); }
}
public class Full Constructors {
public static void f() throws MyException {
System.out рппШГВозбуждаем MyException из fO"). throw new MyException();
}
public static void g() throws MyException {
System, out. pri ntl n( "Возбуждаем MyException из g(D; throw new MyException("Создано в g()");
}
public static void main(String[] args) { try {
f();
} catch(MyException e) {
e.printStackTrace(System.err);
}
try {
g();
} catch(MyException e) {
e.pri ntStackTrace(System
}
} /* Output:
Возбуждаем MyException из f()
MyException
at Ful1 Constructors.f(Ful1 Constructors.java:11) at Full Constructors main(FullConstructors.java-19) Возбуждаем MyException из g() MyException Создано в g()
at Full Constructors g(Ful1 Constructors java:15) at FullConstructors.main(FullConstructors.java 24)
Изменения незначительны — появилось два конструктора, определяющие способ создания объекта MyException. Во втором конструкторе используется конструктор родительского класса с аргументом String, вызываемый ключевым словом super.
В обработчике исключений вызывается метод printStackTrace() класса Throwable (базового для Exception). Этот метод выводит информацию о последовательности вызовов, которая привела к точке возникновения исключения. В нашем примере информация направляется в System.out, но вызов по умолчанию направляет информацию в стандартный поток ошибок:
e.printStackTraceO,
Регистрация исключений
Вспомогательное пространство имен java.utiLlogging позволяет зарегистрировать информацию об исключениях в журнале. Базовые средства регистрации достаточно просты:
II exceptions/LoggingExceptions.java // Регистрация исключений с использованием Logger import java.util.logging *; import java.io *;
class LoggingException extends Exception { private static Logger logger =
Logger getLogger("LoggingException"); public LoggingException() {
StringWriter trace = new StringWriter(); printStackTrace(new PrintWriter(trace)), 1ogger.severe(trace.toStri ng()),
public class LoggingExceptions {
public static void main(String[] args) { try {
throw new LoggingException(); } catch(LoggingException e) {
System.err.println("Перехвачено " + e),
}
try {
throw new LoggingExceptionO: } catch(LoggingException e) {
System.err.println("Перехвачено " + e),
} /* Output (85Х match)
Aug 30, 2005 4:02:31 РМ LoggingException