Виртуальная Машина Java (в дальнейшем JVM) обрабатывая code, запускает методы один за другим, начиная с метода
main
. Когда она доходит до очередного метода, говорится, что этот метод находится на вершине стека. После полного выполнения метода, он удаляется из стека, и сменяется следующим в очереди. Для демонстрации принципа, наберите данный code:
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...
GO TO FULL VERSION