Wie man Java-Ausnahmen richtig behandelt

Wie man Java-Ausnahmen richtig behandelt

Als Programmier-Neuling ist das Konzept von Ausnahmebehandlung kann schwer sein, den Kopf herumzuwickeln. Nicht, dass das Konzept selbst schwierig wäre, aber die Terminologie kann es fortgeschrittener erscheinen lassen, als es ist. Und es ist ein so leistungsstarkes Feature, dass es anfällig für Missbrauch und Missbrauch ist.





In diesem Artikel erfahren Sie, was Ausnahmen sind, warum sie wichtig sind, wie Sie sie verwenden und welche Fehler Sie vermeiden sollten. Die meisten modernen Sprachen haben eine Art Ausnahmebehandlung. Wenn Sie also jemals von Java wegkommen, können Sie die meisten dieser Tipps mitnehmen.





Java-Ausnahmen verstehen

In Java, ein Ausnahme ist ein Objekt, das anzeigt, dass während der Ausführung Ihrer Anwendung etwas Ungewöhnliches (oder „Aussergewöhnliches“) aufgetreten ist. Solche Ausnahmen sind geworfen , was im Grunde bedeutet, dass ein Ausnahmeobjekt erstellt wird (ähnlich wie Fehler 'ausgelöst' werden).





Das Schöne ist, dass du es kannst fangen geworfene Ausnahmen, die es Ihnen ermöglichen, mit dem anormalen Zustand umzugehen und Ihre Anwendung weiterlaufen zu lassen, als ob nichts schief gelaufen wäre. Während beispielsweise ein Nullzeiger in C Ihre Anwendung zum Absturz bringen kann, können Sie mit Java werfen und fangen

NullPointerException

s, bevor eine Null-Variable die Möglichkeit hat, einen Absturz zu verursachen.



Denken Sie daran, dass eine Ausnahme nur ein Objekt ist, aber mit einer wichtigen Eigenschaft: Sie muss aus dem

Exception

Klasse oder eine Unterklasse von





Exception

. Während Java über alle Arten von integrierten Ausnahmen verfügt, können Sie auf Wunsch auch eigene erstellen. Einige der die häufigsten Java-Ausnahmen enthalten:

  • NullPointerException
  • NumberFormatException
  • IllegalArgumentException
  • RuntimeException
  • IllegalStateException

Was passiert also, wenn Sie eine Ausnahme auslösen?





Zuerst sucht Java in der Methode 'unmittelbar', um zu sehen, ob Code vorhanden ist, der die von Ihnen ausgelöste Ausnahme behandelt. Wenn kein Handler vorhanden ist, prüft er die Methode, die die aktuelle Methode aufgerufen hat, um festzustellen, ob dort ein Handle vorhanden ist. Wenn nicht, wird die Methode betrachtet, die aufgerufen hat das Methode und dann die nächste Methode usw. Wenn die Ausnahme nicht abgefangen wird, druckt die Anwendung einen Stack-Trace und stürzt dann ab. (Eigentlich ist es nuancierter als nur ein Absturz, aber das ist ein fortgeschrittenes Thema, das den Rahmen dieses Artikels sprengt.)

ZU Stack-Trace ist eine Liste aller Methoden, die Java beim Suchen nach einem Ausnahmehandler durchlaufen hat. So sieht ein Stacktrace aus:

Exception in thread 'main' java.lang.NullPointerException
at com.example.myproject.Book.getTitle(Book.java:16)
at com.example.myproject.Author.getBookTitles(Author.java:25)
at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

Daraus können wir viel mitnehmen. Zuerst war die geworfene Ausnahme a

NullPointerException

. Es geschah im

getTitle()

-Methode in Zeile 16 von Book.java. Diese Methode wurde aufgerufen von

getBookTitles()

in Zeile 25 von Author.java. Dass Methode wurde aufgerufen von

main()

in Zeile 14 von Bootstrap.java. Wie Sie sehen, wird das Debugging einfacher, wenn Sie all dies wissen.

Aber auch hier liegt der wahre Vorteil von Ausnahmen darin, dass Sie den anormalen Zustand „behandeln“ können, indem Sie die Ausnahme abfangen, die Dinge richtig einstellen und die Anwendung ohne Absturz fortsetzen.

Verwenden von Java-Ausnahmen in Code

Sagen wir, du hast

someMethod()

das nimmt eine ganze Zahl und führt eine Logik aus, die brechen könnte, wenn die ganze Zahl kleiner als 0 oder größer als 100 ist. Dies könnte ein guter Ort sein, um eine Ausnahme auszulösen:

was bedeutet sim nicht bereitgestellt mm2?
public void someMethod(int value) {
if (value 100) {
throw new
IllegalArgumentException

Um diese Ausnahme abzufangen, müssen Sie dorthin gehen

someMethod()

heißt und benutze die Try-Catch-Block :

public void callingMethod() {
try {
someMethod(200);
someOtherMethod();
} catch (IllegalArgumentException e) {
// handle the exception in here
}
// ...
}

Alles innerhalb der Versuchen block wird der Reihe nach ausgeführt, bis eine Ausnahme ausgelöst wird. Sobald eine Ausnahme geworfen wird, werden alle nachfolgenden Anweisungen übersprungen und die Anwendungslogik springt sofort in die fangen Block.

In unserem Beispiel geben wir den try-Block ein und rufen sofort an

someMethod()

. Da 200 nicht zwischen 0 und 100 liegt, ist an

IllegalArgumentException

ist geworfen. Dies beendet sofort die Ausführung von

someMethod()

, überspringt den Rest der Logik im try-Block (

someOtherMethod()

wird nie aufgerufen) und setzt die Ausführung innerhalb des catch-Blocks fort.

Was würde passieren, wenn wir anrufen

someMethod(50)

stattdessen? Die

IllegalArgumentException

würde nie geworfen werden.

someMethod()

wie gewohnt ausführen würde. Der try-Block würde wie gewohnt ausgeführt und aufrufen

someOtherMethod()

wenn someMethod() abgeschlossen ist. Wann

someOtherMethod()

endet, würde der Catch-Block übersprungen und

callingMethod()

würde weitermachen.

Beachten Sie, dass Sie mehrere catch-Blöcke pro try-Block haben können:

public void callingMethod() {
try {
someMethod(200);
someOtherMethod();
} catch (IllegalArgumentException e) {
// handle the exception in here
} catch (NullPointerException e) {
// handle the exception in here
}
// ...
}

Beachten Sie auch, dass eine optionale Endlich Block existiert auch:

public void method() {
try {
// ...
} catch (Exception e) {
// ...
} finally {
// ...
}
}

Der Code in einem finally-Block ist immer ausgeführt, egal was. Wenn Sie im try-Block eine return-Anweisung haben, wird der finally-Block ausgeführt, bevor die Methode verlassen wird. Wenn Sie im catch-Block eine weitere Ausnahme auslösen, wird der finally-Block ausgeführt, bevor die Ausnahme ausgelöst wird.

Sie sollten den finally-Block verwenden, wenn Sie Objekte haben, die vor dem Ende der Methode bereinigt werden müssen. Wenn Sie beispielsweise eine Datei im try-Block geöffnet und später eine Ausnahme ausgelöst haben, können Sie mit dem finally-Block die Datei schließen, bevor Sie die Methode verlassen.

Beachten Sie, dass Sie einen finally-Block ohne einen catch-Block haben können:

public void method() {
try {
// ...
} finally {
// ...
}
}

Auf diese Weise können Sie alle erforderlichen Bereinigungen durchführen und gleichzeitig ausgelösten Ausnahmen erlauben, den Methodenaufrufstapel zu verbreiten (d. h. Sie möchten die Ausnahme hier nicht behandeln, müssen jedoch zuerst bereinigen).

Geprüfte vs. ungeprüfte Ausnahmen in Java

Im Gegensatz zu den meisten Sprachen unterscheidet Java zwischen geprüfte Ausnahmen und ungeprüfte Ausnahmen (z.B. C# hat nur ungeprüfte Ausnahmen). Eine geprüfte Ausnahme muss in der Methode abgefangen werden, in der die Ausnahme ausgelöst wird, sonst wird der Code nicht kompiliert.

Um eine geprüfte Ausnahme zu erstellen, erweitern Sie von

Exception

. Um eine ungeprüfte Ausnahme zu erstellen, erweitern Sie von

RuntimeException

.

Jede Methode, die eine geprüfte Ausnahme auslöst, muss dies in der Methodensignatur mit dem wirft Stichwort. Da Javas eingebaute

IOException

eine geprüfte Ausnahme ist, wird der folgende Code nicht kompiliert:

public void wontCompile() {
// ...
if (someCondition) {
throw new IOException();
}
// ...
}

Sie müssen zuerst deklarieren, dass eine geprüfte Ausnahme ausgelöst wird:

public void willCompile() throws IOException {
// ...
if (someCondition) {
throw new IOException();
}
// ...
}

Beachten Sie, dass eine Methode so deklariert werden kann, dass sie eine Ausnahme auslöst, aber niemals eine Ausnahme auslöst. Trotzdem muss die Ausnahme abgefangen werden, sonst wird der Code nicht kompiliert.

Wann sollten Sie aktivierte oder nicht markierte Ausnahmen verwenden?

Die offizielle Java-Dokumentation hat eine Seite zu dieser Frage . Es fasst den Unterschied mit einer prägnanten Faustregel zusammen: „Wenn von einem Client vernünftigerweise erwartet werden kann, dass er sich von einer Ausnahme erholt, machen Sie sie zu einer geprüften Ausnahme. Wenn ein Client die Ausnahme nicht wiederherstellen kann, machen Sie sie zu einer ungeprüften Ausnahme.'

Aber diese Richtlinie kann veraltet sein. Einerseits führen geprüfte Ausnahmen zu robusterem Code. Auf der anderen Seite hat keine andere Sprache Ausnahmen auf die gleiche Weise geprüft wie Java, was zwei Dinge zeigt: Erstens ist die Funktion nicht nützlich genug für andere Sprachen, um sie zu stehlen, und zweitens kann man absolut ohne sie leben. Außerdem funktionieren geprüfte Ausnahmen nicht gut mit Lambda-Ausdrücken, die in Java 8 eingeführt wurden.

Richtlinien für die Verwendung von Java-Ausnahmen

Ausnahmen sind nützlich, aber leicht missbraucht und missbraucht. Hier sind ein paar Tipps und Best Practices, die Ihnen helfen, ein Durcheinander zu vermeiden.

  • Ziehen Sie spezifische Ausnahmen gegenüber allgemeinen Ausnahmen vor. Verwenden Sie |_+_| über |_+_| wenn möglich, andernfalls verwenden Sie |_+_| über |_+_| wenn möglich.
  • Niemals fangen |_+_| ! Die |_+_| Klasse erweitert tatsächlich |_+_| , und der catch-Block funktioniert tatsächlich mit |_+_| oder jede Klasse, die Throwable erweitert. Die |_+_| Klasse erweitert auch |_+_| , und du willst nie ein |_+_| . fangen weil |_+_| s weisen auf schwerwiegende nicht behebbare Probleme hin.
  • Niemals fangen |_+_| ! |_+_| verlängert |_+_| , also jeder Block, der |_+_| . fängt wird auch |_+_| . fangen , und das ist eine sehr wichtige Ausnahme, mit der Sie sich nicht anlegen möchten (insbesondere bei Multithread-Anwendungen), es sei denn, Sie wissen, was Sie tun. Wenn Sie nicht wissen, welche Ausnahme Sie stattdessen abfangen sollen, ziehen Sie in Betracht, nichts abzufangen.
  • Verwenden Sie beschreibende Nachrichten, um das Debuggen zu vereinfachen. Wenn Sie eine Ausnahme auslösen, können Sie ein |_+_| . angeben Nachricht als Argument. Auf diese Nachricht kann im catch-Block mit dem |_+_| . zugegriffen werden -Methode, aber wenn die Ausnahme nie abgefangen wird, wird die Nachricht auch als Teil des Stacktrace angezeigt.
  • Versuchen Sie, Ausnahmen nicht abzufangen und zu ignorieren. Um die Unannehmlichkeiten von geprüften Ausnahmen zu umgehen, richten viele Anfänger und faule Programmierer einen Catch-Block ein, lassen ihn jedoch leer. Schlecht! Behandeln Sie es immer elegant, aber wenn Sie es nicht können, drucken Sie zumindest einen Stack-Trace aus, damit Sie wissen, dass die Ausnahme ausgelöst wurde. Sie können dies mit dem |_+_| . tun Methode.
  • Achten Sie darauf, Ausnahmen zu oft zu verwenden. Wenn Sie einen Hammer haben, sieht alles aus wie ein Nagel. Wenn Sie zum ersten Mal etwas über Ausnahmen erfahren, fühlen Sie sich vielleicht verpflichtet, alles in eine Ausnahme umzuwandeln ... bis zu dem Punkt, an dem der größte Teil des Kontrollflusses Ihrer Anwendung auf die Ausnahmebehandlung zurückzuführen ist. Denken Sie daran, Ausnahmen sind für 'außergewöhnliche' Vorkommnisse gedacht!

Jetzt sollten Sie mit Ausnahmen vertraut genug sein, um zu verstehen, was sie sind, warum sie verwendet werden und wie Sie sie in Ihren eigenen Code integrieren können. Wenn Sie das Konzept nicht vollständig verstehen, ist das in Ordnung! Es hat eine Weile gedauert, bis es in meinem Kopf „Klick“ gemacht hat, also haben Sie nicht das Gefühl, dass Sie es überstürzen müssen. Lass dir Zeit.

Haben Sie Fragen? Kennen Sie andere ausnahmebezogene Tipps, die ich übersehen habe? Teile sie in den Kommentaren unten!

Teilen Teilen Tweet Email So erstellen Sie ein Datenflussdiagramm zur Visualisierung von Daten eines beliebigen Projekts

Datenflussdiagramme (DFD) jedes Prozesses helfen Ihnen zu verstehen, wie Daten von der Quelle zum Ziel fließen. So erstellen Sie es!

Weiter lesen
Verwandte Themen
  • Programmierung
  • Java
Über den Autor Joel Lee(1524 Artikel veröffentlicht)

Joel Lee ist seit 2018 Chefredakteur von MakeUseOf. Er hat einen B.S. in Informatik und über neun Jahre professionelle Schreib- und Redaktionserfahrung.

So setzen Sie eine Roku-Fernbedienung zurück
Mehr von Joel Lee

Abonniere unseren Newsletter

Abonnieren Sie unseren Newsletter für technische Tipps, Rezensionen, kostenlose E-Books und exklusive Angebote!

Klicken Sie hier, um zu abonnieren