Das abnormale englische Wort ist eine Ausnahme, und die wörtliche Übersetzung bedeutet "Unfall, Ausnahme", was abnormale Situationen bedeutet. Tatsächlich sind Ausnahmen im Wesentlichen Programmfehler, einschließlich Programmlogikfehler und Systemfehler.
Ein Vorwort
Jeder ist mit der Handhabung der Java -Ausnahme vertraut. Im Allgemeinen gibt es zwei Punkte:
1. Ausnahme werfen: Ausnahme werfen
class SimpleException {public void a () löst Ausnahme aus {neue Ausnahme (); };}2. Ausnahmen ausfallen:
public class myException {public static void main (String [] args) {myException e = new myException (); SimpleException se = new SimpleException (); try {se.a (); } catch (Ausnahme e1) {e1.printstacktrace (); }}} class SimpleException {public void a () löst eine Ausnahme aus {neue Ausnahme (); };}In diesem Artikel werden einige Details zu dieser ausführlicheren Basis erörtert.
Zwei benutzerdefinierte Ausnahmeklasse
Die Java -Sprache bietet uns viele Ausnahmeklassen, aber manchmal müssen wir immer noch die Ausnahmeklassen anpassen, um Code zu schreiben:
Klasse SimpleException erweitert die Ausnahme {};
Nach der Erstellung können wir den Versuch verwenden, um es zu erfassen:
public class myException {public static void main (String [] args) {myException e = new myException (); versuche {ea (); } catch (SimpleException e1) {e1.printstacktrace (); }} public void a () löst SimpleException aus {throw New SimpleException (); }} class SimpleException erweitert die Ausnahme {};Wir definieren eine Methode a () in myException, lassen Sie eine einfache Ausnahme ausgelöst, dann nennen wir diese Methode in main () und fangen diese Ausnahme mit Try Catch auf:
SimpleException at MyException.a(MyException.java:15) at MyException.main(MyException.java:8) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.delegatingMethodaccessorimpl.invoke (delegatingMethodaccessorimpl.java:43) bei Java.lang.reflect.method.invoke (methody.java:606) bei com.intellij.rt.execution.apply.application.
Das Ergebnis nach Zusammenstellung und Ausführung basiert hauptsächlich auf den ersten drei Zeilen. Hier sind einige Punkte zu erklären:
1. Geben Sie den Ausnahmetyp an: (Ausnahmespezifikation)
Wenn wir eine Ausnahme in eine Methode auswerfen müssen, verwenden wir Throw und fügen eine Instanz einer Ausnahmeklasse hinzu. Das Programm bringt die entsprechende Ausnahme in das Client -Programm (das Programm, das diesen Code aufruft) und beendet hier (entspricht der Rückgabe). Beachten Sie auch, dass wir beim Definieren dieser Methode den Ausnahmetyp angeben müssen. Zum Beispiel wird der folgende Code eine einfache Ausnahme ausgelöst
öffentliche void a () wirft eine einfache Ausnahme aus
2. Werfen Sie mehrere Ausnahmen aus:
public void a () löst SimpleException, aException, Bexception {neue SimpleException () aus; }Verschiedene Ausnahmeklassen können durch Kommas getrennt werden. In diesem Fall müssen wir nicht jede Ausnahmeklasseninstanz () werfen, aber der Client -Code muss jede Ausnahmeklasse aufnehmen:
public class myException {public static void main (String [] args) {myException e = new myException (); versuche {ea (); } catch (SimpleException e1) {e1.printstacktrace (); } catch (Bexception e1) {e1.printstacktrace (); } catch (aException e1) {e1.printstacktrace (); }} public void a () löst SimpleException, aException, Bexception {town SimpleException () aus; }} class SimpleException erweitert die Ausnahme {}; Klasse aException erweitert die Ausnahme {} Klasse Bexception erweitert die Ausnahme {} Drei Stapelspuren
Unabhängig davon, ob es sich um Ausnahmen oder Ausnahmen fangen und bearbeiten, ist es unser Ziel, ein robusteres Programm zu schreiben, das in hohem Maße von den Ausnahmeinformationen des Java -Ausnahmemechanismus abhängt, und der Träger ist Stack Trace.
Im vorherigen Code verwenden wir PrintStacktrace () direkt aus Ausnahmeinformationen. Tatsächlich können wir auch die GetStacktrace () -Methode verwenden, um eine Sammlung von StacktraceElements zu erhalten. Wenn Sie eine Idee zur Hand haben, können Sie zunächst nach der StacktraceElement -Klasse suchen und feststellen, dass sie die serialisierbare Schnittstelle implementiert und sich dann die Klassenbeschreibung ansehen:
/** * Ein Element in einer Stapelverfolgung, wie von {@link * Throwable#getStacktrace ()} zurückgegeben. Jedes Element repräsentiert einen einzelnen Stapelrahmen. * Alle Stapelrahmen, mit Ausnahme der oben im Stapel, stellen * eine Methodeaufruf dar. Der Rahmen oben im Stapel repräsentiert den Ausführungspunkt *, an dem die Stapelspur erzeugt wurde. Typischerweise * Dies ist der Punkt, an dem das Throwable, das der Stapelspur entspricht, erstellt wurde. * * @Since 1.4 * @Author Josh Bloch *///Es ist klar, dass jede Instanz dieser Klasse ein Element der Stapelspur ist, das einen Stapelrahmen darstellt, und die Stapelspur wird von der GetStacktrace () -Methode zurückgegeben. Ich habe mehrmals versucht, Folgendes zu übersetzen, aber ich fand es nicht gut, also konnte ich den Code einfach direkt schreiben, um ihn zu erklären:
public class myException {public static void main (String [] args) {myException e = new myException (); EA (); public void a () {try {thrower New Exception (); } catch (Ausnahme e) {StackTraceElement [] ste = e.getStacktrace (); System.out.println (Ste.Length); }}}Wir definieren die Methode A, lassen Sie eine Ausnahmeausnahme beim Erfassen und dann ein StacktraceElement -Array durch die Methode GetStacktrace () und drucken Sie die Länge des Arrays aus:
7
Vorgang mit dem Ausgangscode 0 abgeschlossen
Wir haben den Code ein wenig geändert und aufgehört, Ausnahmen in a zu fangen. Wir definieren eine Methode B neu, damit sie Ausnahmen erfasst, während sie A:
public class myException {public static void main (String [] args) {myException e = new myException (); eb (); } public void b () {try {a (); } catch (Ausnahme e) {StackTraceElement [] ste = e.getStacktrace (); System.out.println (Ste.Length); }} public void a () löst Ausnahme aus {neue Ausnahme (); }}Die Ergebnisse sind wie folgt:
8
Vorgang mit dem Ausgangscode 0 abgeschlossen
Mach dir keine Sorgen, werfen wir einen Blick auf etwas Interessantes:
public class myException {public static void main (String [] args) {myException exception = new myException (); try {exception.c (); } catch (Ausnahme e) {StackTraceElement [] ste = e.getStacktrace (); System.out.println (Ste.Length); System.out.println ("-----------------------------------------------------------"); für (stacktraceElement s: e.getStacktrace ()) {System.out.println (S.GetClassName ()+": Methode"+s.getMethodname ()+"at line"+s.getLineNumber ()); } System.out.println ("-------------------------------------------------------"); }} public void c () löst Ausnahme aus {try {a (); } catch (Ausnahme e) {throw e; }} public void a () löst Ausnahme aus {neue Ausnahme (); }}Hier sind die Ergebnisse:
8 ----------------------------------------------------- line57sun.reflect.delegatingMethodAccessorimpl: Methode in Line43java.lang.reflect.method: Methode in Line606com.intellij.rt.execution.application.Application.Appmain: Methode Main bei Line144 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Das heißt, GetStacktrace () gibt einen Stapel zurück, der einige grundlegende Informationen vom Anrufer (main ()) an die anfängliche Ausnahme (a ()) enthält. Im obigen Code fangen wir die Ausnahme auf, wenn wir die A -Methode in der C -Methode aufrufen und sie erneut durch Würfe werfen. Die Methode, die die C-Methode aufruft, kann die Ausnahme fangen und verarbeiten, oder Sie können sich weiterentwickeln, damit die Anrufer auf hoher Ebene (nahe am Boden des Stapels) damit umgehen können. Obwohl Rethrow sehr bequem ist, gibt es einige Probleme. Schauen wir uns den folgenden Code an:
public class myException {public static void main (String [] args) {myException exception = new myException (); try {exception.c (); } catch (Ausnahme e) {e.printstacktrace (System.out); }} public void c () löst Ausnahme aus {try {a (); } catch (Ausnahme e) {throw e; }} public void a () löst Ausnahme aus {neue Ausnahme ("Ausnahme von a ()"); }} java.lang.Exception: Ausnahme von a () at myException.a (myexception.java:40) at myException.c (myexception.java:30) at myException.main (myexception.java:21)Wir sind in C in C und drucken es mit E.PrintStacktrace () in Main aus. Sie können sehen, dass die gedruckte Stapelspur noch zu einem gehört. Wenn wir Stapelspuren in C verwandeln wollen, können wir es so schreiben:
public class myException {public static void main (String [] args) {myException exception = new myException (); try {exception.c (); } catch (Ausnahme e) {e.printstacktrace (System.out); }} public void c () löst Ausnahme aus {try {a (); } catch (Ausnahme e) {// throw e; Throw (Ausnahme) E. fillinStacktrace (); }} public void a () löst Ausnahme aus {neue Ausnahme ("Ausnahme von a ()"); }} java.lang.Exception: Ausnahme von a () at myException.c (myexception.java:22) at myException.main (myexception.java:10) Vier Ausnahmeketten
Schauen wir uns ein Szenario an:
public class testException {public static void main (String [] args) {testException testException = new TestException (); try {testException.c (); } catch (cexception e) {e.printstacktrace (); }} public void a () löscht aexception {aException aException = new aException ("Dies ist eine Ausnahme"); Wirf Aexception; } public void b () löst Bexception aus {try {a (); } catch (aException e) {neue Bexception werfen ("Dies ist B -Ausnahme"); }} public void c () löscht Cexception {try {b (); } catch (Bexception e) {neue Cexception werfen ("Dies ist C -Ausnahme"); }}} class aException erweitert die Ausnahme {public aException (String msg) {Super (msg); }} class Bexception erweitert die Ausnahme {public Bexception (String msg) {Super (msg); }} class Cexception erweitert die Ausnahme {public Cexception (String msg) {Super (msg); }}Drei Ausnahmeklassen Aexception, Bexception und Cexception werden erstellt, dann wird AException in a (), Aexception in B () gefangen und Bexception wird geworfen, und schließlich wird Bexception in C () gefangen und Cexception wird geworfen und das Ergebnis wird wie folgt gedruckt:
Cexception: Dies ist eine C -Ausnahme bei testException.c (testException.java:31) bei testException.main (testException.java:8)
OK, wir sehen nur, dass die Informationen von Cexception, Aexception und Bexception verloren gegangen sind, und die Funktion der Ausnahmekette wird herauskommen, siehe Code:
public class testException {public static void main (String [] args) {testException testException = new TestException (); try {testException.c (); } catch (cexception e) {e.printstacktrace (); }} public void a () löscht aexception {aException aException = new aException ("Dies ist eine Ausnahme"); Wirf Aexception; } public void b () löst Bexception aus {try {a (); } catch (aException e) {// neue Bexception werfen ("This is b Exception"); Bexception Bexception = new Bexception ("Dies ist B -Ausnahme"); Bexception.initcause (e); Bexception werfen; }} public void c () löscht Cexception {try {b (); } catch (Bexception e) {// Neue Cexception ("This is C -Ausnahme"); Cexception cexception = new Cexception ("Dies ist C -Ausnahme"); Cexception.initcause (e); Cexception werfen; }}} class aException erweitert die Ausnahme {public aException (String msg) {Super (msg); }} class Bexception erweitert die Ausnahme {public Bexception (String msg) {Super (msg); }} class Cexception erweitert die Ausnahme {public Cexception (String msg) {Super (msg); }}Wir verwenden die Initcause () -Methode, um die Ausnahmeinformationen zu verbinden, und das Ergebnis lautet wie folgt:
Cexception: Dies ist eine C -Ausnahme bei testException.c (testException.java:35) bei testException.main (testException.java:8) at sun.reflect.nativemethodaccessorimpl.invoke0 (native Methode) bei sunefect.nativemethodaccessorimPl.Invoke (nativemethodact.javacessorimPl.Invoke) (NATIVEMETHOCTICACTICACACACACACACACACACA: sun.reflect.delegatingMethodaccessorimpl.invoke (delegatingMethodaccessorimpl.java:43) bei Java.lang.reflect.method.invoke (methody.java:606) at com.intellij.rt.Apply.Apply.Application. ist B -Ausnahme bei testException.b (testException.java:24) at testException.c (testException.java:32) ... 6 meecaupt von: aexception: Dies ist eine Ausnahme bei testException.a (testException.java:15) bei testException.b (testException.java:21) ... 7 mehr Process fertig mit dem EXIT -Code 0, der mit dem EXIT -Code 0 beendet ist.
Das fünf Postskription
Tatsächlich gibt es immer noch viele Dinge, die man über die Handhabung von Java -Ausnahmen besprechen kann, aber weil ich nur begrenzte Erfahrung habe, kann ich es nicht zu tief verstehen und der am häufigsten verwendete ist.
Versuchen Sie {...} catch (Ausnahme E) {...} endlich {// Code, der ausgeführt wird, unabhängig davon, ob die Ausnahme gefangen oder verarbeitet wird, z. B. das Schließen von IO -Operationen}Aber egal was passiert, wir müssen Java noch dafür danken, dass sie uns mit dem Ausnahmemechanismus geliefert haben. Es ist wie ein Ältester, der uns von Zeit zu Zeit führt und uns bei Codierung weniger gelangweilt macht :)