JavaRush /Java Blog /Random-TK /Стек-трейс Java
IvanDurov
Dereje

Стек-трейс Java

Toparda çap edildi
Виртуальная Машина Java (в дальнейшем JVM) обрабатывая code, запускает методы один за другим, начиная с метода main. Когда она доходит до очередного метода, говорится, что этот метод находится на вершине стека. После полного выполнения метода, он удаляется из стека, и сменяется следующим в очереди. Для демонстрации принципа, наберите данный code: Стек-трейс 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.ArithmeticException: / by zero at errorhandling.errorChecking.m2(<u>errorChecking.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 Вы смотрите на нечто, называемое стек-трейс. Три строки, подчёркнутые голубым, ссылаются на ваши методы, и могут быть найдены в: Name_пакета.Name_класса.Name_метода Первая сверху строка — это место, где ошибка возникла — в методе m2. Java проследила, что бы она была обработана ArithmeticException, которая вылавливает ошибки деления на ноль. В методах m2, m1 и main нет обработчика ошибок. Так что программа обработала её обработчиком ошибок по-умолчанию. Измените ваш метод m1 на следующий:

try {
    System.out.println("Первый метод передаёт привет!(m1)");
    m2( );
}
catch (ArithmeticException err) {
    System.out.println(err.getMessage());
}
Теперь мы обернули метод m2 в блок try. В части catch, мы используем тип исключения, что был выявлен в стек-трейсе — ArithmeticException. Запустите code снова, и в окне вывода увидите следующее: Метод Main успешно запущен Первый метод передаёт привет!(m1) / by zero Метод Main заканчивает свою работу Заметьте, что сообщение об ошибке вывелось How: "/ by zero". Метод m2 не был выполнен fully, а был остановлен, когда возникла ошибка. Затем контроль был передан обратно m1. Это произошло благодаря тому, что блок catch сам распознавал ошибку, JVM не стала обращаться к стандартному обработчику ошибок, а вывела сообщение находящееся между фигурными скобками блока catch. Обратите внимание, что сама программа не была остановлена. Контроль, How обычно перешёл к методу main, откуда m1 был вызван. И последняя строка метода main, таки смогла вывести на экран "End Main method". Это имеет очень-очень важное meaning. Если бы вам нужно было meaning из m1, для последующей работы где-то в main. И если значения там не окажется, то ваша программа может отработать совсем не так, How вы ожидаете. Когда вы увидите стек-трейс в окне вывода, просто знайте, что первая строка — это то место, где проблема возникла, а остальные строки (если конечно они есть), куда исключение было передано вверх по стеку, обычно заканчивая методом main. Перевод с сайта homeandlearn.co.uk Говорим спасибо: Серегею Сысоеву, Treefeed...
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION