Трассировка стека исключений в Java

307
15 августа 2021, 07:50

Метод fillInStackTrace(), реализованный в классе Throwable позволяет получить объект типа Throwable, с сохранением трассировки стека вызывающего объекта в только что созданном объекте. Причина моего вопроса в следующем:

class one {
    static Throwable w_exc(){
        ArithmeticException ar_exc = new ArithmeticException();
        Throwable ar_exc_1 = ar_exc.fillInStackTrace();
        return ar_exc_1;}
    public static void main(String[] argc){
        Throwable exc_1 = w_exc();
        StackTraceElement[] stacktrace = exc_1.getStackTrace();
        for (StackTraceElement element : stacktrace){
            System.out.println(element);
        }
        System.out.println(exc_1.toClass());
    }
} 

При выполнении получим:

one.w_exc(one.java:4)
one.main(one.java:7)

Но если перенести вызов метода fillInStackTrace() в метод main():

class one {
    static Throwable w_exc(){
        ArithmeticException ar_exc = new ArithmeticException();
        return ar_exc;}
    public static void main(String[] argc){
        Throwable exc_1 = (w_exc()).fillInStackTrace();
        StackTraceElement[] stacktrace = exc_1.getStackTrace();
        for (StackTraceElement element : stacktrace){
            System.out.println(element);
        }
    }
} 

мы получим

one.main(one.java:6)

т.е. из стека потеряли методы, которые вызывались до этого, хотя в первом варианте сохранились. Так вот, почему в первом внутренние методы сохранились, хотя при возврате объекта из метода они должны были быть вытолкнуты из стека и в обеих случаях возвращается объект одного и того же класса? Вопрос может быть несколько простой, но все равно не смог понять. upd. поднимаю

Answer 1

Согласно документации fillInStackTrace() записывает в объект Throwable текущее состояние стека. Если использовать getStackTrace(), результат будет такой же, как в первом случае.

public static void main(String[] argc) {
    Throwable result = w_exc();
    // Throwable exc_1 = result.fillInStackTrace();
    // System.out.println(exc_1==result);
    for (StackTraceElement element: result.getStackTrace()) {
        System.out.println(element);
    }
}

Обратите внимание, если раскомментировать строку с fillInStackTrace(), StackTrace в result будет изменён, нового объекта Throwable не создаётся.

READ ALSO
Как вызвать NullPointerException в Java, не используя throw?

Как вызвать NullPointerException в Java, не используя throw?

Нужен наиболее простой способ вызвать NullPointerException

147
Цикл завершается раньше, чем хотелось бы

Цикл завершается раньше, чем хотелось бы

Сколько попыток понадобится сделать компьютеру чтобы подобрать из рандомных букв слово которое вы ввели?

223
Обработать изображение из URL в SPRING BOOT

Обработать изображение из URL в SPRING BOOT

Не совсем понимаю как можно полностью вытащить изображение по url с помощью SpringУ меня простой REST контроллер post

142
Оптимизация spinner

Оптимизация spinner

Мой кастомный Spinner при первом клике на него долго открывается (~3 сек)Он состоит из 25 обьектов класса Person

150