JavaRush /Java блог /Random UA /Стек-трейс Java
IvanDurov
25 рівень

Стек-трейс Java

Стаття з групи Random UA
Віртуальна Машина Java (надалі JVM) обробляючи код, запускає методи один за одним, починаючи з методу main. Коли вона сягає чергового методу, говориться, що це метод перебуває в вершині стека. Після повного виконання методу він видаляється зі стека і змінюється наступним у черзі. Для демонстрації принципу наберіть цей код: Стек-трейс Java - 1
package errorhandling;

public class errorChecking {
    public static void main(String[] args) {
        System.out.println("Метод Main успешно запущен");
        m1();
        System.out.println("Метод Main заканчивает свою работу");
    }

    static void m1() {
        System.out.println("Первый метод передаёт привет!(m1)");
        m2();
    }

    static void m2() {
        System.out.println("Второй метод передаёт привет(m2)");
    }
}
У нас три методи: метод main, метод m1і метод m2. Коли програма стартує, на вершині стека розташований метод main. Усередині методу mainвикликається метод m1. Викликаючись, він стрибає на верхівку стека. Метод m1у свою чергу викликає метод m2. Тепер вже метод m2стрибає на верхівку стека, тимчасово відстороняючи m1. На секунду уявіть це - mainзверху m1і на вершині m2! Зробивши свої справи, m2завершується, і контроль повертається до m1. Метод m1, завершуючись, теж видаляється зі стека, і управління знову отримує метод main. Запустіть вашу програму та подивіться на вікно виводу: Метод Main успішно запущений Перший метод передає привіт!(m1) Другий метод передає привіт(m2) Метод Main закінчує свою роботу Якщо щось піде не так у методі m2, JVM (Віртуальна Машина Джава, ви пам'ятаєте, так?) буде шукати обробників помилок наприклад блок try … catch. Якщо методі m1оброблювача помилок немає, то виняток буде передано методу m1, сподіваючись, що він зможе її обробити. Якщо тут не виявить обробника помилок, то виняток знову перейде по стеку вгору, цього разу на метод main. Якщо метод mainне взаємодіє з виключенням, ви отримаєте дивне повідомлення про помилку, надруковане у вікні виводу. Як приклад, приведіть ваш метод m2до такого виду:
static void m2() {
    int x = 10;
    int y = 0;
    double z = x / y;
    System.out.println( z );
    System.out.println("Method Two - m2");
}
Цей метод містить помилку поділу на нуль. А ось повний варіант програми, повірте зі своїм:
package errorhandling;

public class errorChecking {
    public static void main(String[] args) {
        System.out.println("Метод Main успешно запущен");
        m1();
        System.out.println("Метод Main заканчивает свою работу");
    }

    static void m1() {
        System.out.println("Первый метод передаёт привет!(m1)");
        m2();
    }

    static void m2() {
        int x = 10;
        int y = 0;
        double z = x / y;
        System.out.println( z );
        System.out.println("Method Two - m2");
    }
}
Запустіть програму і подивіться, що видасть вам вікно виводу: Метод Main успішно запущений Перший метод передає привіт!(m1) Exception in thread "main" java.lang. java:17</u>) at errorhandling.errorChecking.m1(<u>Solution.java:11</u>) at errorhandling.errorChecking.main(<u>>Solution.java:5</u>) Process finished with exit code 1 Ви дивитеся на щось так зване стек-трейс. Три рядки, підкреслені блакитним, посилаються на ваші методи, і можуть бути знайдені в: ім'я_пакета.ім'я_класса.ім'я_метода Перший згори рядок — це місце, де помилка виникла — у методі m2. Java простежила, що вона була оброблена ArithmeticException, яка виловлює помилки поділу на нуль. У методах m2іm1mainнемає оброблювача помилок. Так що програма обробила її обробником помилок за умовчанням. Змініть метод m1на наступний:
try {
    System.out.println("Первый метод передаёт привет!(m1)");
    m2( );
}
catch (ArithmeticException err) {
    System.out.println(err.getMessage());
}
Тепер ми обернули метод m2у блок try. У частині catch, ми використовуємо тип виключення, який був виявлений у стек-трейсі - ArithmeticException. Запустіть код знову, і у вікні виводу побачите наступне: Метод Main успішно запущений Перший метод передає привіт ! Метод m2не було виконано повністю, а було зупинено, коли виникла помилка. Потім контроль було передано назад m1. Це сталося завдяки тому, що блок catchсам розпізнавав помилку, JVM не стала звертатися до стандартного оброблювача помилок, а вивела повідомлення, що знаходиться між фігурними дужками блоку.catch. Зверніть увагу, що саму програму не було зупинено. Контроль, як завжди перейшов до методу main, звідки m1був викликаний. І останній рядок методу mainтаки зміг вивести на екран " End Main method ". Це має дуже важливе значення. Якщо вам потрібно було значення з m1, для подальшої роботи десь у main. І якщо значення там не виявиться, то ваша програма може відпрацювати зовсім не так, як ви очікуєте. Коли ви побачите стек-трейс у вікні виводу, просто знайте, що перший рядок - це те місце, де проблема виникла, а решта рядків (якщо звичайно вони є), куди виняток було передано вгору по стеку, зазвичай закінчуючи методом main. Переклад із сайту homeandlearn.co.uk Дякуємо: Сергію Сисоєву, Treefeed...
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ