Ненормальным английским словом является исключением, а буквальный перевод означает «авария, исключение», что означает ненормальные ситуации. Фактически, исключения являются по существу ошибки программы, включая ошибки логики программы и системные ошибки.
Предисловие
Все знакомы с обработкой исключений Java, в целом есть два момента:
1. Выбросить исключение: бросьте исключение
Class SimpleException {public void a () бросает исключение {бросить новое исключение (); };}2. Участники составления:
открытый класс myException {public static void main (string [] args) {myException e = new myexception (); SimpleException se = new SimpleException (); try {se.a (); } catch (Exception e1) {e1.printstackTrace (); }}} класс SimpleException {public void a () бросает Exception {Throw New Exclive (); };}В этой статье будут обсуждаться некоторые детали на этой более глубокой основе.
Два пользовательских исключения класса
Язык Java предоставляет нам много классов исключений, но иногда нам все еще приходится настроить классы исключений для удобства написания кода:
Class SimpleException расширяет исключение {};
После создания мы можем использовать попытку поймать, чтобы захватить его:
открытый класс myException {public static void main (string [] args) {myException e = new myexception (); try {ea (); } catch (simpleException e1) {e1.printstacktrace (); }} public void a () бросает SimpleException {Throw New SimpleException (); }} класс SimpleException расширяет Exception {};Мы определяем метод a () в MyException, пусть он бросает исключение SimpleException, затем мы называем этот метод в Main () и поймаем это исключение, используя Try Catch:
Простое восприятие на myexception.a (myexception.java:15) на myexception.main (myexception.java:8) на sun.reflect.nativemethodaccessympl.invoke0 (нативный метод) на sun.reflect.nativemethodaccessorimpl.invoke (NativemethodaccessOr sun.reflect.delegatingmethodaccessorimpl.invoke (делегирование methodaccessorimpl.java:43) на java.lang.reflect.method.invoke (method.java:606) на com.intellij.rt.execution.application.appmain.main (appmain.jav.
Результат после компиляции и выполнения в основном основан на первых трех строках. Вот несколько моментов, которые нужно объяснить:
1. Укажите тип исключения: (спецификация исключения)
Когда нам нужно бросить исключение в методе, мы используем бросок и добавляем экземпляр класса исключений. Программа бросит соответствующее исключение из клиентской программы (программа, которая вызывает этот код) и выйдет здесь (эквивалентно для возврата). Также обратите внимание, что мы должны указать тип исключения при определении этого метода. Например, следующий код вызовет исключение SimpleException Exception
public void a () бросает простое
2. Выбросьте несколько исключений:
public void a () бросает простое восприятие, aexception, bexception {throw new simplexception (); }Различные классы исключений могут быть разделены запятыми. В этом случае нам не нужно бросать каждый экземпляр класса исключений (), но клиент -код должен улавливать каждый класс исключений:
открытый класс myException {public static void main (string [] args) {myException e = new myexception (); try {ea (); } catch (simpleException e1) {e1.printstacktrace (); } catch (bexception e1) {e1.printstacktrace (); } catch (aexception e1) {e1.printstacktrace (); }} public void a () выбрасывает простое, aexception, bexception {throw new simplexception (); }} класс SimpleException Excement Exception {}; класс Aexception Extends Exception {} класс Bexception Extends Exception {} Три стека трассировки
Независимо от того, бросает ли это исключения или улавливает и обрабатывает исключения, наша цель состоит в том, чтобы написать более надежную программу, которая в значительной степени зависит от информации об исключении, предоставленной механизмом исключений Java, а его носитель - Stack Trace.
В предыдущем коде мы напрямую используем printStackTrace () для распечатки информации об исключении. На самом деле, мы также можем использовать метод getStackTrace () для получения коллекции StackTraceElement. Если у вас есть идея под рукой, вы можете сначала найти класс StackTraceElement, и вы можете обнаружить, что он реализует интерфейс, сериализуемый, а затем взгляните на описание класса:
/** * Элемент в трассировке стека, как возвращается {@link * throwable#getStackTrace ()}. Каждый элемент представляет кадр одного стека. * Все кадры стека, за исключением того, что в верхней части стека представляют собой вызов метода. Кадр в верхней части стека представляет собой точку выполнения *, в которой была сгенерирована трасса стека. Как правило, * это точка, в которой был создан бросаемый, соответствующий трассировке стека *. * * @since 1.4 * @author Джош Блох */Понятно, что каждый экземпляр этого класса является элементом трассировки стека, представляющего кадр стека, а трассировка стека возвращается методом getStackTrace (). Я пытался перевести следующее несколько раз, но я чувствовал, что это не очень хорошо, поэтому я мог просто написать код напрямую, чтобы объяснить:
открытый класс myException {public static void main (string [] args) {myException e = new myexception (); ea (); public void a () {try {бросить новое исключение (); } catch (Exception e) {StackTraceElement [] ste = e.getStackTrace (); System.out.println (Ste.length); }}}Мы определяем метод A, пусть он бросает исключение исключение при его захвате, а затем мы получаем массив StackTraceElement через метод getStackTrace () и распечатывайте длину массива:
7
Процесс завершен с кодом выхода 0
Мы немного изменили код и перестали ловить исключения в. Мы переопределяем метод B, чтобы он ловил исключения, вызывая:
открытый класс myException {public static void main (string [] args) {myException e = new myexception (); eb (); } public void b () {try {a (); } catch (Exception e) {StackTraceElement [] ste = e.getStackTrace (); System.out.println (Ste.length); }} public void a () бросает exection {Throw New Exception (); }}Результаты следующие:
8
Процесс завершен с кодом выхода 0
Не волнуйтесь, давайте посмотрим на что -то интересное:
public class myexception {public static void main (string [] args) {myException exception = new myexception (); try {exception.c (); } catch (Exception e) {StackTraceElement [] ste = e.getStackTrace (); System.out.println (Ste.length); System.out.println ("---------------------------------------------------------------"); for (StackTraceElement S: e.getStackTrace ()) {System.out.println (s.getClassname ()+": метод"+s.getmethodname ()+"at line"+s.getlineNumber ()); } System.out.println ("---------------------------------------------------------------"); }} public void c () бросает Exception {try {a (); } catch (Exception e) {throw e; }} public void a () бросает exection {Throw New Exception (); }}Вот результаты:
8 --------------------------------------------------------------------------- MyException: Метод A AT LINE43MYEXCEPTION: Метод C AT LINE39MYEXCEPTIO line57sun.reflect.DelegatingMethodAccessorImpl:method invoke at line43java.lang.reflect.Method:method invoke at line606com.intellij.rt.execution.application.AppMain:method main at line144---------------------------------------------------------------Process finished with exit code 0
То есть GetStackTrace () возвращает стек, который содержит некоторую основную информацию от вызывающего (main ()) к первоначальному исключению броска (a ()). В приведенном выше коде мы поймаем исключение при вызове метода A в методе C и бросаем его снова через броски. Метод, вызывая метод C, может завоевать и обрабатывать исключение, или вы можете продолжить бросить броски, чтобы позволить абонентам более высокого уровня (около нижней части стека) обрабатывать его. Хотя Rethrow очень удобен, есть некоторые проблемы. Давайте посмотрим на следующий код:
public class myexception {public static void main (string [] args) {myException exception = new myexception (); try {exception.c (); } catch (Exception e) {e.printstackTrace (System.out); }} public void c () бросает Exception {try {a (); } catch (Exception e) {throw e; }} public void a () бросает исключение {бросить новое исключение ("Исключение из a ()"); }} java.lang.exception: Исключение из a () at myexception.a (myexception.java:40) на myexception.c (myexception.java:30) на myexception.main (myexception.java:21)Мы пересматриваем E в C и распечатываем его с помощью e.printstacktrace () в Main. Вы можете видеть, что трассировка печатного стека все еще принадлежит. Если мы хотим превратить трассировку стека в C, мы можем написать это так:
public class myexception {public static void main (string [] args) {myException exception = new myexception (); try {exception.c (); } catch (Exception e) {e.printstackTrace (System.out); }} public void c () бросает Exception {try {a (); } catch (Exception e) {// бросить E; бросить (исключение) e.fillinstacktrace (); }} public void a () бросает исключение {бросить новое исключение ("Исключение из a ()"); }} java.lang.exception: исключение из a () at myexception.c (myexception.java:22) на myexception.main (myexception.java:10) Четыре цепочка исключения
Давайте посмотрим на сценарий:
public class testexception {public static void main (string [] args) {testexception testexception = new TestException (); try {testexception.c (); } catch (cexception e) {e.printstacktrace (); }} public void a () бросает aexception {aexception aexception = new aexception («Это исключение»); бросить aexception; } public void b () бросает bexception {try {a (); } catch (aexception e) {бросить новое Bexception ("Это B Exception"); }} public void c () Throws Cexception {try {b (); } catch (bexception e) {бросить новое Cexception («Это C Exception»); }}} класс Aexception Exceptends Exception {public aexception (String msg) {super (msg); }} класс Bexception расширяет Exception {public bexception (String msg) {super (msg); }} класс Cexception расширяет Exception {public cexception (String msg) {super (msg); }}Три класса исключения Aexception, Bexception и Cexception создаются, затем Aexception брошено в A (), Aexception попадает в B (), и BEXCEPTION выбрасывается, и, наконец, BException попадает в C (), а выброс в Cexception отбрасывается, и результат напечатано следующим образом:
Cexception: это исключение C на testexception.c (testexception.java:31) на testexception.main (testexception.java:8)
ОК, мы видим только информацию о выяснении, Aexception и Bexception, и функция цепочки исключений появится, см. Код:
public class testexception {public static void main (string [] args) {testexception testexception = new TestException (); try {testexception.c (); } catch (cexception e) {e.printstacktrace (); }} public void a () бросает aexception {aexception aexception = new aexception («Это исключение»); бросить aexception; } public void b () бросает bexception {try {a (); } catch (aexception e) {// бросить новое Bexception ("Это B Exception"); Bexception bexception = new Bexception («Это B исключение»); bexception.initcause (e); Бросьте Bexception; }} public void c () Throws Cexception {try {b (); } catch (bexception e) {// бросить новое Cexception ("Это C Exception"); Cexception cexception = new Cexception («Это C Exception»); cexception.initcause (e); бросить цикцию; }}} класс Aexception Exceptends Exception {public aexception (String msg) {super (msg); }} класс Bexception расширяет Exception {public bexception (String msg) {super (msg); }} класс Cexception расширяет Exception {public cexception (String msg) {super (msg); }}Мы используем метод initCause () для подключения информации об исключении, и результат заключается в следующем:
Cexception: это C -исключение на testexception.c (testexception.java:35) на testexception.main (testexception.java:8) на sun.reflect.nativemethodaccessormpl.invoke0 (нативный метод) на sun.reflect.nativemethodaccessormpl.invoke (nativemethodaccesscesscesscesscessp. sun.reflect.delegatingmethodaccessoriMpl.invoke (делегирование methodaccessoriMpl.java:43) на java.lang.reflect.method.invoke (method.java:606) на com.intellij.rt.excution.application.appmain.main.main (appmain.java. IS Exception at testexception.b (testexception.java:24) at testexception.c (testexception.java:32) ... 6 MorecaSeden: aexception: Это исключение на TestException.A (TestException.java:15) на TestException.B (testException.java:21) ... 7 больше
Пять постскриптум
На самом деле, есть еще много вещей, чтобы обсудить об обращении с исключением Java, но поскольку у меня ограниченный опыт, я не могу понять это слишком глубоко, и наиболее часто используется
try {...} catch (Exception e) {...} Наконец {// код, который будет выполнен независимо от того, будет ли исключение поймано или обработано, например, закрытие операций ввода -вывода}Но несмотря ни на что, мы все еще должны поблагодарить Java за предоставление нам механизма исключений. Это как старейшина, время от времени руководствуя нас и делает нас менее скучными при кодировании :)