Философия Java


Повторное выбрасывание исключений - часть 2


originating the exception in f() Inside g(), e.printStackTrace() java.lang.Exception: thrown from f() at Rethrowing.f(Rethrowing.java:8) at Rethrowing.g(Rethrowing.java:12) at Rethrowing.main(Rethrowing.java:24) Caught in main, e.printStackTrace() java.lang.Exception: thrown from f() at Rethrowing.f(Rethrowing.java:8) at Rethrowing.g(Rethrowing.java:12) at Rethrowing.main(Rethrowing.java:24)

Так что стек трассировки исключения всегда помнит исходное место, не имеет значения, сколько прошло времени перед повторным выбрасыванием.

Если закомментировать строку 17, а строку 18 раскомментировать, будет использоваться функция fillInStackTrace( ), и получим результат:

originating the exception in f() Inside g(), e.printStackTrace() java.lang.Exception: thrown from f() at Rethrowing.f(Rethrowing.java:8) at Rethrowing.g(Rethrowing.java:12) at Rethrowing.main(Rethrowing.java:24) Caught in main, e.printStackTrace() java.lang.Exception: thrown from f() at Rethrowing.g(Rethrowing.java:18) at Rethrowing.main(Rethrowing.java:24)

Поскольку fillInStackTrace( ) в строке 18 становится новой исходной точкой исключения.

Класс Throwable должен появиться в спецификации исключения для g( ) и main( ), потому что fillInStackTrace( ) производит ссылку на объект Throwable. Так как Throwable - это базовый класс для Exception, можно получить объект, который является Throwable, но не Exception, так что обработчик для Exception в main( ) может промахнуться. Чтобы убедится, что все в порядке, компилятор навязывает спецификацию исключения для Throwable. Например, исключение в следующем примере не перехватывается в main( ):

//: c10:ThrowOut.java

public class ThrowOut { public static void

main(String[] args) throws Throwable { try { throw new Throwable(); } catch(Exception e) { System.err.println("Caught in main()"); } } } ///:~

Также возможно вновь выбросить исключение, отличающееся от того, которое вы поймали. Если вы делаете это, вы получаете сходный эффект, как если бы вы использовали fillInStackTrace( ) — информация об оригинальном состоянии исключения теряется, а то, с чем вы остаетесь - это информация, относящаяся к новому throw:

//: c10:RethrowNew.java




Начало  Назад  Вперед