Looking for java Keywords? Try Ask4Keywords

Java Language Расширенные возможности исключений


пример

В этом примере описаны некоторые дополнительные функции и прецеденты для исключений.

Проверка программной таблицы программно

Java SE 1.4

Основное использование стека стека исключений заключается в предоставлении информации об ошибке приложения и его контексте, чтобы программист мог диагностировать и исправлять проблему. Иногда его можно использовать для других вещей. Например, для класса SecurityManager может потребоваться проверка стека вызовов, чтобы решить, следует ли доверять коду, вызывающему вызов.

Вы можете использовать исключения для проверки стека вызовов программно следующим образом:

    Exception ex = new Exception();   // this captures the call stack
    StackTraceElement[] frames = ex.getStackTrace();
    System.out.println("This method is " + frames[0].getMethodName());
    System.out.println("Called from method " + frames[1].getMethodName());

Есть несколько важных предостережений по этому поводу:

  1. Информация, доступная в StackTraceElement , ограничена. Существует больше информации, чем отображается printStackTrace . (Значения локальных переменных в кадре недоступны.)

  2. В javadocs для getStackTrace() что JVM разрешено оставлять рамки:

    Некоторые виртуальные машины могут при некоторых обстоятельствах опустить один или несколько кадров стека из трассировки стека. В крайнем случае виртуальная машина, которая не имеет информации о трассировке стека, относящейся к этому методу, разрешает возвращать массив нулевой длины из этого метода.

Оптимизация конструкции исключения

Как упоминалось в другом месте, построение исключения является довольно дорогостоящим, поскольку оно влечет за собой захват и запись информации обо всех кадрах стека в текущем потоке. Иногда мы знаем, что эта информация никогда не будет использоваться для данного исключения; например, stacktrace никогда не будет напечатана. В этом случае существует трюк реализации, который мы можем использовать в пользовательском исключении, чтобы не захватывать информацию.

Информация о кадре стека, необходимая для stacktraces, записывается, когда конструкторы Throwable называют метод Throwable.fillInStackTrace() . Этот метод является public , что означает, что подкласс может его переопределить. Хитрость заключается в том, чтобы переопределить метод, унаследованный от Throwable тем, который ничего не делает; например

  public class MyException extends Exception {
      // constructors

      @Override 
      public void fillInStackTrace() {
          // do nothing
      }
  }

Проблема с этим подходом заключается в том, что исключение, которое переопределяет fillInStackTrace() никогда не может захватить стек, и бесполезно в сценариях, где вам это нужно.

Стирание или замена стека

Java SE 1.4

В некоторых ситуациях stacktrace для исключения, созданного обычным способом, содержит либо неверную информацию, либо информацию, которую разработчик не хочет показывать пользователю. Для этих сценариев Throwable.setStackTrace может использоваться для замены массива объектов StackTraceElement который содержит информацию.

Например, для удаления информации об стеках исключений можно использовать следующее:

 exception.setStackTrace(new StackTraceElement[0]);

Подавленные исключения

Java SE 7

Java 7 представила конструкцию try-with-resources и связанную с ней концепцию исключения исключений. Рассмотрим следующий фрагмент:

try (Writer w = new BufferedWriter(new FileWriter(someFilename))) {
    // do stuff
    int temp = 0 / 0;    // throws an ArithmeticException
}

Когда выбрано исключение, try вызовет функцию close() на w которая будет очищать любой буферный вывод, а затем закрыть FileWriter . Но что произойдет, если IOException будет IOException при очистке вывода?

Случается, что любое исключение, которое бросается при очистке ресурса, подавляется . Исключение поймано и добавлено в список исключенных исключений первичного исключения. Затем try-with-resources продолжат очистку других ресурсов. Наконец, основное исключение будет восстановлено.

Аналогичная картина возникает, если исключение было выбрано во время инициализации ресурса или если блок try завершился нормально. Исключение составляет первое исключение, которое является основным исключением, а последующие, возникающие из-за очистки, подавляются.

Подавленные исключения могут быть извлечены из основного объекта исключения, вызвав getSuppressedExceptions .