Sind diese Code-Anweisungen gleichwertig? Gibt es einen Unterschied zwischen ihnen?
private void calculateArea() throws Exception {
....do something
}
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
Antworten:
Ja, es gibt einen großen Unterschied - letzterer verschluckt die Ausnahme (zeigt sie zugegebenermaßen), während der erste sie ausbreiten lässt. (Ich gehe davon aus, dass
showException
das nicht neu geworfen wird.)Wenn Sie also die erste Methode aufrufen und "etwas tun" fehlschlägt, muss der Aufrufer die Ausnahme behandeln. Wenn Sie die zweite Methode aufrufen und "etwas tun" fehlschlägt, wird dem Aufrufer überhaupt keine Ausnahme angezeigt. Dies ist im Allgemeinen eine schlechte Sache, es sei denn, er
showException
hat die Ausnahme wirklich behandelt, Fehler behoben und im Allgemeinen sichergestellt dascalculateArea
hat seinen Zweck erreicht.Sie werden in der Lage sein , dies zu sagen, weil Sie nicht die erste Methode ohne aufrufen können entweder fangen
Exception
selbst oder erklären , dass Ihre Methode es werfen könnte.quelle
Zuerst
throws Exception
muss der Anrufer das erledigenException
. Der zweite fängt und verarbeitetException
intern, sodass der Anrufer keine Ausnahmebehandlung durchführen muss.quelle
Ja. Für die deklarierte Version ist
throws Exception
der aufrufende Code erforderlich, um die Ausnahme zu behandeln, für die explizit behandelte Version jedoch nicht.dh einfach:
Verschieben der Last der Behandlung der Ausnahme auf den Anrufer:
quelle
Ja, es gibt einen großen Unterschied zwischen ihnen. Im ersten Codeblock übergeben Sie die Ausnahme an den aufrufenden Code. Im zweiten Codeblock erledigen Sie das selbst. Welche Methode richtig ist, hängt ganz davon ab, was Sie tun. In einigen Fällen soll Ihr Code die Ausnahme behandeln (wenn eine Datei nicht gefunden wird und Sie sie beispielsweise erstellen möchten), in anderen Fällen soll der aufrufende Code die Ausnahme behandeln (eine Datei wird nicht gefunden) und sie müssen ein neues angeben oder es erstellen).
Auch im Allgemeinen möchten Sie keine generische Ausnahme abfangen. Stattdessen möchten Sie nur bestimmte fangen, z. B.
FileNotFoundException
oderIOException
weil sie unterschiedliche Bedeutungen haben können.quelle
Es gibt ein bestimmtes Szenario, in dem wir keine Würfe verwenden können. Wir müssen Try-Catch verwenden. Es gibt eine Regel "Eine überschriebene Methode kann keine zusätzliche Ausnahme auslösen als die, die ihre übergeordnete Klasse auslöst". Wenn es eine zusätzliche Ausnahme gibt, die mit try-catch behandelt werden sollte. Betrachten Sie dieses Code-Snippet. Es gibt eine einfache Basisklasse
und es ist abgeleitete Klasse:
Wenn wir thread.sleep () aufrufen müssen, müssen wir try-catch verwenden, hier können wir nicht verwenden:
weil überschriebene Methode keine zusätzlichen Ausnahmen auslösen kann.
quelle
Ich gehe davon aus, dass Sie sich mit "identisch" auf Verhalten beziehen.
Ein Verhalten einer Funktion kann bestimmt werden durch:
1) Rückgabewert
2) Ausgelöste Ausnahmen
3) Nebenwirkungen (dh Änderungen im Heap, im Dateisystem usw.)
In diesem Fall gibt die erste Methode jede Ausnahme weiter, während die zweite keine aktivierte Ausnahme auslöst und die meisten nicht aktivierten Ausnahmen ebenfalls verschluckt, sodass das Verhalten anders ist.
Wenn Sie jedoch garantieren, dass "etwas tun" niemals eine Ausnahme auslöst, ist das Verhalten identisch (obwohl der Compiler in der ersten Version vom Aufrufer verlangt, die Ausnahme zu behandeln).
--bearbeiten--
Aus Sicht des API-Designs unterscheiden sich die Methoden in ihrem Vertrag völlig. Es wird auch nicht empfohlen, eine Klassenausnahme zu werfen. Versuchen Sie, etwas Spezifischeres zu werfen, damit der Anrufer die Ausnahme besser behandeln kann.
quelle
Wenn Sie eine Ausnahme ausgelöst haben, sollte die untergeordnete Methode (die diese überschreibt) die Ausnahme behandeln
Beispiel:
quelle
Oft möchten Sie, dass der Anrufer die Ausnahme behandelt. Angenommen, der Aufrufer ruft eine Methode auf, die eine andere Methode aufruft, die eine andere Methode aufruft. Anstatt dass jede Methode die Ausnahme behandelt, können Sie sie einfach beim Aufrufer behandeln. Es sei denn, Sie möchten etwas in einer der Methoden tun, wenn diese Methode fehlschlägt.
quelle
Der Aufrufer dieser Methode muss diese Ausnahme entweder abfangen oder deklarieren, dass sie in ihrer Methodensignatur erneut ausgelöst wird.
Im folgenden Try-Catch-Block-Beispiel. Der Aufrufer dieser Methode muss sich nicht um die Behandlung der Ausnahme kümmern, da diese bereits behoben wurde.
quelle
Dies löst die Ausnahme aus, sodass der Anrufer für die Behandlung dieser Ausnahme verantwortlich ist. Wenn der Anrufer die Ausnahme jedoch nicht behandelt, wird sie möglicherweise an jvm übergeben, was zu einer abnormalen Beendigung des Programms führen kann.
Während im zweiten Fall:
Hier wird die Ausnahme vom Angerufenen behandelt, sodass keine Möglichkeit einer abnormalen Beendigung des Programms besteht.
Try-Catch ist der empfohlene Ansatz.
IMO,
Löst ein Schlüsselwort aus, das hauptsächlich mit geprüften Ausnahmen verwendet wird, um den Compiler zu überzeugen, garantiert jedoch nicht die normale Beendigung des Programms.
Das Schlüsselwort delegiert die Verantwortung für die Ausnahmebehandlung an
den Aufrufer (JVM oder eine andere Methode).
Das Schlüsselwort "Throws" ist nur für aktivierte Ausnahmen erforderlich. Für nicht aktivierte Ausnahmen wird das Schlüsselwort "throw" nicht verwendet.
quelle