Joshua Bloch in " Effective Java " sagte das
Verwenden Sie geprüfte Ausnahmen für wiederherstellbare Bedingungen und Laufzeitausnahmen für Programmierfehler (Punkt 58 in der 2. Ausgabe).
Mal sehen, ob ich das richtig verstehe.
Hier ist mein Verständnis einer überprüften Ausnahme:
try{
String userInput = //read in user input
Long id = Long.parseLong(userInput);
}catch(NumberFormatException e){
id = 0; //recover the situation by setting the id to 0
}
1. Wird das oben Gesagte als geprüfte Ausnahme angesehen?
2. Ist RuntimeException eine nicht aktivierte Ausnahme?
Hier ist mein Verständnis einer ungeprüften Ausnahme:
try{
File file = new File("my/file/path");
FileInputStream fis = new FileInputStream(file);
}catch(FileNotFoundException e){
//3. What should I do here?
//Should I "throw new FileNotFoundException("File not found");"?
//Should I log?
//Or should I System.exit(0);?
}
4. Könnte der obige Code nicht auch eine geprüfte Ausnahme sein? Kann ich versuchen, die Situation so wiederherzustellen? Kann ich? (Hinweis: Meine dritte Frage befindet sich catch
oben)
try{
String filePath = //read in from user input file path
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
}catch(FileNotFoundException e){
//Kindly prompt the user an error message
//Somehow ask the user to re-enter the file path.
}
5. Warum machen die Leute das?
public void someMethod throws Exception{
}
Warum lassen sie die Ausnahme aufblasen? Ist es nicht besser, den Fehler früher zu behandeln? Warum sprudeln?
6. Soll ich die genaue Ausnahme in die Luft sprudeln lassen oder sie mit Ausnahme maskieren?
Unten sind meine Lesungen
Wann werden aktivierte und nicht aktivierte Ausnahmen ausgewählt?
DataSeries
Klasse, die Daten enthält, die immer in zeitbasierter Reihenfolge bleiben müssen. Es gibt eine Methode, umDataPoint
am Ende von a eine neue hinzuzufügenDataSeries
. Wenn mein gesamter Code während des gesamten Projekts ordnungsgemäß funktioniert,DataPoint
sollte am Ende niemals ein Code hinzugefügt werden, der ein vorheriges Datum zu dem bereits am Ende hat. Jedes Modul im gesamten Projekt wird mit dieser Binsenweisheit erstellt. Ich überprüfe diese Bedingung jedoch und löse eine ungeprüfte Ausnahme, wenn dies passiert. Warum? Wenn es passiert, möchte ich wissen, wer dies tut und es beheben.Antworten:
Viele Leute sagen, dass geprüfte Ausnahmen (dh diese, die Sie explizit abfangen oder neu werfen sollten) überhaupt nicht verwendet werden sollten. Sie wurden beispielsweise in C # entfernt, und die meisten Sprachen haben sie nicht. Sie können also immer eine Unterklasse von
RuntimeException
(nicht aktivierte Ausnahme) auslösen.Ich denke jedoch, dass geprüfte Ausnahmen nützlich sind - sie werden verwendet, wenn Sie den Benutzer Ihrer API dazu zwingen möchten, darüber nachzudenken, wie mit der Ausnahmesituation umgegangen werden soll (wenn sie wiederherstellbar ist). Es ist nur so, dass geprüfte Ausnahmen in der Java-Plattform überbeansprucht werden, was dazu führt, dass die Leute sie hassen.
Hier ist meine erweiterte Sicht auf das Thema .
Zu den besonderen Fragen:
Ist das
NumberFormatException
eine geprüfte Ausnahme?Nr.
NumberFormatException
Ist deaktiviert (= ist Unterklasse vonRuntimeException
). Warum? Ich weiß es nicht. (aber es hätte eine Methode geben sollenisValidInteger(..)
)Ist
RuntimeException
eine ungeprüfte Ausnahme?Ja genau.
Was soll ich hier machen?
Es hängt davon ab, wo sich dieser Code befindet und was passieren soll. Wenn es sich in der UI-Ebene befindet, fangen Sie es ab und zeigen Sie eine Warnung an. Wenn es in der Service-Schicht ist - fangen Sie es überhaupt nicht - lassen Sie es sprudeln. Schluck die Ausnahme einfach nicht. Wenn in den meisten Fällen eine Ausnahme auftritt, sollten Sie eine der folgenden Optionen auswählen:
Könnte der obige Code nicht auch eine geprüfte Ausnahme sein? Kann ich versuchen, die Situation so wiederherzustellen? Kann ich?
Es hätte sein können. Aber nichts hindert Sie daran, auch die ungeprüfte Ausnahme abzufangen
Warum fügen Leute Klasse
Exception
in die Throws-Klausel ein?Meistens, weil die Leute faul sind, darüber nachzudenken, was sie fangen und was sie neu werfen sollen. Werfen
Exception
ist eine schlechte Praxis und sollte vermieden werden.Leider gibt es keine einzige Regel, mit der Sie bestimmen können, wann zu fangen, wann neu zu werfen, wann aktiviert und wann nicht aktivierte Ausnahmen zu verwenden sind. Ich bin damit einverstanden, dass dies viel Verwirrung und viel schlechten Code verursacht. Das allgemeine Prinzip wird von Bloch angegeben (Sie haben einen Teil davon zitiert). Und das allgemeine Prinzip besteht darin, eine Ausnahme auf die Ebene zu werfen, auf der Sie damit umgehen können.
quelle
Ob etwas eine "geprüfte Ausnahme" ist, hat nichts damit zu tun, ob Sie es abfangen oder was Sie im catch-Block tun. Es ist eine Eigenschaft von Ausnahmeklassen. Alles, was eine Unterklasse mit
Exception
Ausnahme vonRuntimeException
und seine Unterklassen ist, ist eine geprüfte Ausnahme.Der Java-Compiler zwingt Sie, entweder geprüfte Ausnahmen abzufangen oder sie in der Methodensignatur zu deklarieren. Es sollte die Sicherheit des Programms verbessern, aber die Mehrheit scheint der Meinung zu sein, dass es die damit verbundenen Designprobleme nicht wert ist.
Denn das ist der ganze Punkt der Ausnahmen. Ohne diese Möglichkeit würden Sie keine Ausnahmen benötigen. Sie ermöglichen es Ihnen, Fehler auf einer von Ihnen gewählten Ebene zu behandeln, anstatt Sie zu zwingen, sie in Methoden auf niedriger Ebene zu behandeln, in denen sie ursprünglich auftreten.
quelle
Throwable
halber , wie der Javadoc für sagt: "Throwable und jede Unterklasse von Throwable, die nicht auch eine Unterklasse von RuntimeException oder Error ist, gelten als geprüfte Ausnahmen"Wird das oben Gesagte als geprüfte Ausnahme angesehen? Nein Die Tatsache , dass Sie eine Ausnahme sind Handling macht es nicht ein ,
Checked Exception
wenn es einRuntimeException
.Ist
RuntimeException
einunchecked exception
? JaChecked Exceptions
sindsubclasses
vonjava.lang.Exception
Unchecked Exceptions
sindsubclasses
vonjava.lang.RuntimeException
Aufrufe, die geprüfte Ausnahmen auslösen, müssen in einem try {} -Block eingeschlossen oder in einer höheren Ebene im Aufrufer der Methode behandelt werden. In diesem Fall muss die aktuelle Methode deklarieren, dass diese Ausnahmen ausgelöst werden, damit die Aufrufer geeignete Vorkehrungen treffen können, um die Ausnahme zu behandeln.
Hoffe das hilft.
A: Ja, dies ist eine sehr gute Frage und eine wichtige Überlegung zum Design. Die Klasse Exception ist eine sehr allgemeine Ausnahmeklasse und kann zum Umschließen interner Ausnahmen auf niedriger Ebene verwendet werden. Sie sollten eine benutzerdefinierte Ausnahme erstellen und in diese einschließen. Aber, und eine große - Niemals in der zugrunde liegenden ursprünglichen Grundursache dunkel. Gehen Sie zum Beispiel
Don't ever
wie folgt vor:Gehen Sie stattdessen wie folgt vor:
Das Wegfressen der ursprünglichen Grundursache ist ein Albtraum für Produktionsunterstützungsteams, auf die sie nur Zugriff auf Anwendungsprotokolle und Fehlermeldungen erhalten. Letzteres ist zwar ein besseres Design, aber viele Leute verwenden es nicht oft, weil Entwickler die zugrunde liegende Nachricht einfach nicht an den Anrufer weitergeben. Machen Sie sich also eine feste Notiz: Geben Sie
Always pass on the actual exception
zurück, ob eine anwendungsspezifische Ausnahme vorliegt oder nicht.RuntimeException
s sollten in der Regel nicht versucht werden. Sie signalisieren in der Regel einen Programmierfehler und sollten in Ruhe gelassen werden. Stattdessen sollte der Programmierer die Fehlerbedingung überprüfen, bevor er Code aufruft, der zu a führen kannRuntimeException
. Zum Beispiel:Dies ist eine schlechte Programmierpraxis. Stattdessen hätte eine Nullprüfung wie folgt durchgeführt werden sollen:
Aber es gibt Zeiten, in denen eine solche Fehlerprüfung teuer ist, wie z. B. die Formatierung von Zahlen.
Hier lohnt sich die Fehlerprüfung vor dem Aufruf nicht, da im Wesentlichen der gesamte Konvertierungscode von Zeichenfolge in Ganzzahl innerhalb der parseInt () -Methode dupliziert wird - und ist fehleranfällig, wenn sie von einem Entwickler implementiert wird. Es ist also besser, Try-Catch einfach wegzulassen.
Also
NullPointerException
undNumberFormatException
beidesRuntimeExceptions
, das Abfangen von aNullPointerException
sollte durch eine ordnungsgemäße Nullprüfung ersetzt werden, während ich empfehle, einNumberFormatException
explizit abzufangen, um eine mögliche Einführung von fehleranfälligem Code zu vermeiden.quelle
exception
, sollte ich die genaue Ausnahme sprudeln oder sie mit maskierenException
. Ich schreibe Code über einen alten Code und werdeException
überall in die Luft gesprudelt. Ich frage mich, ob dies das richtige Verhalten ist.LoginFailureException(sqle)
?LoginFailureException
erweitertException
und deklariert wirdpublic LoginFailureException(Throwable cause) { super(cause) }
1. Wenn Sie sich bei einer Ausnahme nicht sicher sind, überprüfen Sie die API:
2. Ja, und jede Ausnahme, die es erweitert.
3 . Es ist nicht erforderlich, dieselbe Ausnahme zu fangen und zu werfen. In diesem Fall können Sie einen neuen Dateidialog anzeigen.
4. FileNotFoundException ist bereits eine aktivierte Ausnahme.
5. Wenn erwartet wird, dass die Methode aufruft
someMethod
, um die Ausnahme abzufangen, kann letztere ausgelöst werden. Es "geht nur den Ball". Ein Beispiel für die Verwendung wäre, wenn Sie es in Ihre eigenen privaten Methoden werfen und stattdessen die Ausnahme in Ihrer öffentlichen Methode behandeln möchten.Eine gute Lektüre ist das Oracle-Dokument selbst: http://download.oracle.com/javase/tutorial/essential/exceptions/runtime.html
Es gibt auch eine wichtige Information in der Java-Sprachspezifikation :
Unterm Strich IMHO ist , dass Sie können jeden fangen
RuntimeException
, aber Sie sind nicht verpflichtet, und in der Tat ist die Umsetzung nicht die gleichen nicht-geprüfte Ausnahmen geworfen halten erforderlich, da diejenigen , die nicht Bestandteil des Vertrages sind.quelle
exception
, sollte ich die genaue Ausnahme sprudeln oder sie mit maskierenException
. Ich schreibe Code über einen alten Code und werdeException
überall in die Luft gesprudelt. Ich frage mich, ob dies das richtige Verhalten ist.1) Nein, eine NumberFormatException ist eine nicht aktivierte Ausnahme. Auch wenn Sie es gefangen haben (das müssen Sie nicht), weil es nicht markiert ist. Dies liegt daran, dass es sich um eine Unterklasse handelt, von
IllegalArgumentException
der eine Unterklasse von istRuntimeException
.2)
RuntimeException
ist die Wurzel aller ungeprüften Ausnahmen. Jede Unterklasse vonRuntimeException
ist deaktiviert. Alle anderen Ausnahmen undThrowable
werden mit Ausnahme von Fehlern (die darunter fallenThrowable
) überprüft .3/4) Sie können den Benutzer darauf hinweisen, dass er eine nicht vorhandene Datei ausgewählt und nach einer neuen gefragt hat. Oder beenden Sie einfach die Benachrichtigung des Benutzers, dass er etwas Ungültiges eingegeben hat.
5) Werfen und Fangen
'Exception'
ist eine schlechte Praxis. Im Allgemeinen können Sie jedoch andere Ausnahmen auslösen, damit der Anrufer entscheiden kann, wie er damit umgehen soll. Wenn Sie beispielsweise eine Bibliothek zum Lesen einiger Dateieingaben geschrieben haben und Ihrer Methode eine nicht vorhandene Datei übergeben wurde, wissen Sie nicht, wie Sie damit umgehen sollen. Möchte der Anrufer erneut fragen oder beenden? Sie werfen also die Ausnahme in der Kette zurück zum Anrufer.In vielen Fällen tritt ein
unchecked Exception
Fehler auf, weil der Programmierer die Eingaben nicht überprüft hat (im FallNumberFormatException
Ihrer ersten Frage). Aus diesem Grund ist es optional, sie abzufangen, da es elegantere Möglichkeiten gibt, diese Ausnahmen nicht zu generieren.quelle
exception
, sollte ich die genaue Ausnahme sprudeln oder sie mit maskierenException
. Ich schreibe Code über einen alten Code und werdeException
überall in die Luft gesprudelt. Ich frage mich, ob dies das richtige Verhalten ist.Aktiviert - Anfällig. Eingecheckt in Kompilierungszeit.
ZB .. FileOperations
Nicht überprüft - Aufgrund fehlerhafter Daten. Zur Laufzeit eingecheckt.
Z.B..
Hier ist eine Ausnahme auf fehlerhafte Daten zurückzuführen, die während der Kompilierungszeit in keiner Weise ermittelt werden können.
quelle
Überprüfte Ausnahmen werden zur Kompilierungszeit von der JVM und den zugehörigen Ressourcen (Dateien / Datenbank / Stream / Socket usw.) überprüft. Das Motiv der aktivierten Ausnahme ist, dass die Anwendung zur Kompilierungszeit, wenn die Ressourcen nicht verfügbar sind, ein alternatives Verhalten definieren sollte, um dies im catch / finally-Block zu behandeln.
Nicht aktivierte Ausnahmen sind rein programmatische Fehler, falsche Berechnungen, Nulldaten oder sogar Fehler in der Geschäftslogik können zu Laufzeitausnahmen führen. Es ist absolut in Ordnung, ungeprüfte Ausnahmen im Code zu behandeln / abzufangen.
Erklärung von http://coder2design.com/java-interview-questions/
quelle
Meine absolute Lieblingsbeschreibung des Unterschieds zwischen ungeprüften und geprüften Ausnahmen findet sich im Java Tutorial-Artikel " Ungeprüfte Ausnahmen - die Kontroverse " (es tut mir leid, dass ich in diesem Beitrag alle Grundkenntnisse habe - aber hey, die Grundlagen sind manchmal die besten):
Das Herzstück von "welche Art von Ausnahme zu werfen ist" ist semantisch (bis zu einem gewissen Grad) und das obige Zitat bietet eine ausgezeichnete Richtlinie (daher bin ich immer noch überwältigt von der Vorstellung, dass C # geprüfte Ausnahmen beseitigt hat - insbesondere, wie Liskov argumentiert ihre Nützlichkeit).
Der Rest wird dann logisch: Auf welche Ausnahmen erwartet der Compiler, dass ich explizit antworte? Diejenigen, von denen Sie erwarten, dass sich der Client erholt.
quelle
Um die letzte Frage zu beantworten (die anderen scheinen oben gründlich beantwortet zu sein): "Soll ich die genaue Ausnahme in die Luft sprudeln lassen oder sie mit Ausnahme maskieren?"
Ich gehe davon aus, dass Sie so etwas meinen:
Nein, deklarieren Sie immer die genaueste mögliche Ausnahme oder eine Liste davon. Die Ausnahmen, für die Sie Ihre Methode als auslösungsfähig deklarieren, sind Bestandteil des Vertrags zwischen Ihrer Methode und dem Aufrufer. Werfen
"FileNotFoundException"
bedeutet, dass der Dateiname möglicherweise nicht gültig ist und die Datei nicht gefunden wird. Der Anrufer muss dies intelligent handhaben. WerfenException
bedeutet "Hey, das passiert nicht. Deal." Welches ist eine sehr armeAPI
.In den Kommentaren zum ersten Artikel gibt es einige Beispiele, bei denen "throw
Exception
" eine gültige und vernünftige Deklaration ist, aber das ist bei den meisten "normal
" Codes, die Sie jemals schreiben werden , nicht der Fall .quelle
Laufzeitausnahmen : Laufzeitausnahmen werden als nicht aktivierte Ausnahmen bezeichnet. Alle anderen Ausnahmen sind geprüfte Ausnahmen und stammen nicht von java.lang.RuntimeException.
Überprüfte Ausnahmen : Eine geprüfte Ausnahme muss irgendwo im Code abgefangen werden. Wenn Sie eine Methode aufrufen, die eine aktivierte Ausnahme auslöst, die aktivierte Ausnahme jedoch nicht irgendwo abfängt, wird Ihr Code nicht kompiliert. Aus diesem Grund werden sie als geprüfte Ausnahmen bezeichnet: Der Compiler prüft, ob sie behandelt oder deklariert werden.
Einige der Methoden in der Java-API lösen geprüfte Ausnahmen aus, sodass Sie häufig Ausnahmebehandlungsroutinen schreiben, um mit Ausnahmen umzugehen, die von Methoden generiert wurden, die Sie nicht geschrieben haben.
quelle
Warum lassen sie die Ausnahme aufblasen? Ist es nicht besser, den Fehler früher zu behandeln? Warum sprudeln?
Angenommen, Sie haben eine Client-Server-Anwendung und der Client hat eine Anforderung für eine Ressource gestellt, die nicht herausgefunden werden konnte, oder für einen anderen Fehler, der möglicherweise auf der Serverseite während der Verarbeitung der Benutzeranforderung aufgetreten ist. Dann ist dies die Pflicht des Servers, um dem Client mitzuteilen, warum er das angeforderte Objekt nicht erhalten konnte. Um dies auf der Serverseite zu erreichen, wird Code geschrieben, um die Ausnahme mit dem Schlüsselwort throw auszulösen, anstatt sie zu schlucken oder zu behandeln. Wenn der Server sie behandelt / schluckt In diesem Fall besteht keine Möglichkeit, dem Kunden mitzuteilen, welcher Fehler aufgetreten ist.
Hinweis: Um eine klare Beschreibung des aufgetretenen Fehlertyps zu erhalten, können Sie ein eigenes Ausnahmeobjekt erstellen und an den Client senden.
quelle
Ich denke, dass geprüfte Ausnahmen eine gute Erinnerung für den Entwickler sind, der eine externe Bibliothek verwendet, dass in Ausnahmesituationen Probleme mit dem Code aus dieser Bibliothek auftreten können.
Weitere Informationen zu geprüften und nicht geprüften Ausnahmen finden Sie hier http://learnjava.today/2015/11/checked-vs-unchecked-exceptions/
quelle
Ich möchte nur einige Gründe hinzufügen, warum geprüfte Ausnahmen überhaupt nicht verwendet werden. Dies ist keine vollständige Antwort, aber ich denke, sie beantwortet einen Teil Ihrer Frage und ergänzt viele andere Antworten.
Immer wenn geprüfte Ausnahmen betroffen sind, befindet sich
throws CheckedException
irgendwo in einer Methodensignatur eine (CheckedException
möglicherweise jede geprüfte Ausnahme). Eine Signatur löst KEINE Ausnahme aus. Das Auslösen von Ausnahmen ist ein Aspekt der Implementierung. Schnittstellen, Methodensignaturen, übergeordnete Klassen, all diese Dinge sollten NICHT von ihren Implementierungen abhängen. Die Verwendung von aktivierten Ausnahmen hier (tatsächlich die Tatsache, dass Sie diethrows
in der Methodensignatur deklarieren müssen) bindet Ihre übergeordneten Schnittstellen an Ihre Implementierungen dieser Schnittstellen.Lassen Sie mich Ihnen ein Beispiel zeigen.
Lassen Sie uns eine schöne und saubere Oberfläche wie diese haben
Jetzt können wir viele Implementierungen von Methoden
foo()
wie diese schreibenClass Foo ist vollkommen in Ordnung. Machen wir jetzt einen ersten Versuch in der Klasse Bar
Diese Klassenleiste wird nicht kompiliert. Da InterruptedException eine aktivierte Ausnahme ist, müssen Sie sie entweder erfassen (mit einem Try-Catch innerhalb der Methode foo ()) oder deklarieren, dass Sie sie auslösen (
throws InterruptedException
zur Methodensignatur hinzufügen ). Da ich diese Ausnahme hier nicht erfassen möchte (ich möchte, dass sie sich nach oben ausbreitet, damit ich sie an anderer Stelle richtig verarbeiten kann), ändern wir die Signatur.Diese Klassenleiste wird auch nicht kompiliert! Die Methode foo () von Bar überschreibt NICHT die Methode foo () von IFoo, da ihre Signaturen unterschiedlich sind. Ich könnte die @ Override-Annotation entfernen, aber ich möchte gegen die Schnittstelle IFoo wie programmieren
IFoo foo;
und später entscheiden, welche Implementierung ich verwenden möchte, wiefoo = new Bar();
. Wenn die Methode foo () von Bar die Methode foo von IFoo nicht überschreibt, wenn ich das tuefoo.foo();
wird die Implementierung von foo () von Bar nicht aufgerufen.Damit Bar
public void foo() throws InterruptedException
IFoos überschreibt,public void foo()
MUSSthrows InterruptedException
ich die Methodensignatur von IFoo ergänzen . Dies führt jedoch zu Problemen mit meiner Foo-Klasse, da sich die Signatur der foo () -Methode von der Signatur der IFoo-Methode unterscheidet. Wenn ich außerdemthrows InterruptedException
zu Foos Methode foo () hinzufügen würde, würde ich einen weiteren Fehler erhalten, der besagt, dass Foos Methode foo () deklariert, dass sie eine InterruptedException auslöst, aber niemals eine InterruptedException auslöst.Wie Sie sehen können (wenn ich gute Arbeit geleistet habe, um dieses Zeug zu erklären), zwingt mich die Tatsache, dass ich eine aktivierte Ausnahme wie InterruptedException auslöse, dazu, meine Schnittstelle IFoo an eine ihrer Implementierungen zu binden, was wiederum Chaos bei IFoo verursacht andere Implementierungen!
Dies ist ein wichtiger Grund, warum geprüfte Ausnahmen SCHLECHT sind. In Kappen.
Eine Lösung besteht darin, die aktivierte Ausnahme zu erfassen, sie in eine nicht aktivierte Ausnahme zu verpacken und die nicht aktivierte Ausnahme auszulösen.
quelle
throws InterruptedException
die Methodensignatur von IFoo ergänzen , ohne irgendetwas in eine Implementierung zu werfen. Es verursacht also kein wirkliches Problem. Wenn Sie in einer Schnittstelle jeden Methodensignaturwurf ausführenException
, hat eine Implementierung nur die Wahl, eine Ausnahme auszulösen oder nicht auszulösen (jede Ausnahme, daException
alle Ausnahmen gekapselt sind).throw Exception
Klausel in ihrer Signatur erstellt, obwohl Ihre Implementierung nichts auslöst oder möglicherweise auslöst eine spezifischere Ausnahme. Aber ich denke immer noch, dass es eine gute Praxis ist, immer eine Ausnahme für die Methode eines Interfaces zu werfen, da der Benutzer wiederum die Wahl hat, etwas zu werfen oder nicht zu werfen.subclasses
zur Klasse gehören,RuntimeException
sind nicht aktivierte Ausnahmen.Exception
aber nicht,RuntimeException
gelten alschecked exceptions
.checked exception
.throws
Klausel bereitstellen , die diechecked-exception
.Exception
Klassen sind so definiert, dass sie überprüft werden, wenn sie als wichtig genug angesehen werden, um sie zu fangen oder zu deklarieren.quelle
Hier ist eine einfache Regel, die Ihnen bei der Entscheidung helfen kann. Es hängt damit zusammen, wie Schnittstellen in Java verwendet werden.
Nehmen Sie Ihre Klasse und stellen Sie sich vor, Sie entwerfen eine Schnittstelle dafür, sodass die Schnittstelle die Funktionalität der Klasse beschreibt, jedoch keine der zugrunde liegenden Implementierungen (wie es eine Schnittstelle tun sollte). Stellen Sie sich vor, Sie könnten die Klasse auf andere Weise implementieren.
Schauen Sie sich die Methoden der Schnittstelle an und berücksichtigen Sie die Ausnahmen, die sie möglicherweise auslösen:
Wenn eine Ausnahme unabhängig von der zugrunde liegenden Implementierung von einer Methode ausgelöst werden kann (mit anderen Worten, sie beschreibt nur die Funktionalität), sollte es sich wahrscheinlich um eine aktivierte Ausnahme in der Schnittstelle handeln.
Wenn eine Ausnahme durch die zugrunde liegende Implementierung verursacht wird, sollte sie sich nicht in der Schnittstelle befinden. Daher muss es sich entweder um eine nicht aktivierte Ausnahme in Ihrer Klasse handeln (da nicht aktivierte Ausnahmen nicht in der Schnittstellensignatur enthalten sein müssen), oder Sie müssen sie umbrechen und als überprüfte Ausnahme, die Teil der Schnittstellenmethode ist, erneut auslösen.
Um zu entscheiden, ob Sie einschließen und erneut werfen sollten, sollten Sie erneut überlegen, ob es für einen Benutzer der Benutzeroberfläche sinnvoll ist, die Ausnahmebedingung sofort zu behandeln, oder ob die Ausnahme so allgemein ist, dass Sie nichts dagegen tun können und dies sollte den Stapel verbreiten. Ist die umschlossene Ausnahme sinnvoll, wenn sie als Funktionalität der neuen Schnittstelle ausgedrückt wird, die Sie definieren, oder ist sie nur ein Träger für eine Reihe möglicher Fehlerzustände, die auch bei anderen Methoden auftreten können? In diesem Fall handelt es sich möglicherweise immer noch um eine aktivierte Ausnahme, andernfalls sollte sie deaktiviert sein.
Normalerweise sollten Sie keine "Bubble-up" -Ausnahmen (Fangen und erneutes Werfen) planen. Entweder sollte eine Ausnahme vom Anrufer behandelt werden (in diesem Fall ist sie aktiviert), oder sie sollte bis zu einem High-Level-Handler reichen (in diesem Fall ist es am einfachsten, wenn sie deaktiviert ist).
quelle
Nur um darauf hinzuweisen, dass Sie die Ausnahme in der Signatur jeder Methode zwischen Ihnen und dem Fang deklarieren müssen, wenn Sie eine aktivierte Ausnahme in einen Code auslösen und der Fang nur wenige Ebenen darüber liegt. Die Kapselung ist also fehlerhaft, da alle Funktionen im Wurfpfad die Details dieser Ausnahme kennen müssen.
quelle
Kurz gesagt, Ausnahmen, die Ihr Modul oder die oben genannten Module zur Laufzeit behandeln sollen, werden als geprüfte Ausnahmen bezeichnet. andere sind ungeprüfte Ausnahmen, die entweder
RuntimeException
oder sindError
.In diesem Video werden aktivierte und deaktivierte Ausnahmen in Java erläutert:
https://www.youtube.com/watch?v=ue2pOqLaArw
quelle
All dies sind geprüfte Ausnahmen. Nicht aktivierte Ausnahmen sind Unterklassen von RuntimeException. Die Entscheidung ist nicht, wie man mit ihnen umgeht, sondern ob Ihr Code sie wirft. Wenn Sie nicht möchten, dass der Compiler Ihnen mitteilt, dass Sie keine Ausnahme behandelt haben, verwenden Sie eine nicht aktivierte Ausnahme (Unterklasse von RuntimeException). Diese sollten für Situationen gespeichert werden, die Sie nicht wiederherstellen können, z. B. Speicherfehler und dergleichen.
quelle
Wenn sich jemand für einen weiteren Beweis interessiert, der geprüfte Ausnahmen nicht mag, lesen Sie die ersten Absätze der beliebten JSON-Bibliothek:
"Obwohl dies eine aktivierte Ausnahme ist, kann sie nur selten wiederhergestellt werden. Die meisten Anrufer sollten diese Ausnahme einfach in eine nicht aktivierte Ausnahme einschließen und erneut auslösen:"
Warum in aller Welt sollte irgendjemand Entwickler dazu bringen, die Ausnahme weiter zu überprüfen, wenn wir sie stattdessen "einfach einpacken" sollten? lol
http://developer.android.com/reference/org/json/JSONException.html
quelle
Überprüfte Ausnahmen :
Die Ausnahmen, die vom Compiler zur reibungslosen Ausführung des Programms zur Laufzeit geprüft werden, werden als geprüfte Ausnahme bezeichnet.
Diese treten zur Kompilierungszeit auf.
Alle Unterklassen der Exception-Klasse mit Ausnahme von RuntimeException sind Checked Exception.
Hypothetisches Beispiel - Angenommen, Sie verlassen Ihr Haus für die Prüfung. Wenn Sie jedoch prüfen, ob Sie Ihr Hallenticket zu Hause mitgenommen haben (Kompilierungszeit), tritt in der Prüfungshalle (Laufzeit) kein Problem auf.
Deaktivierte Ausnahme :
Die Ausnahmen, die vom Compiler nicht geprüft werden, werden als ungeprüfte Ausnahmen bezeichnet.
Diese treten zur Laufzeit auf.
Wenn diese Ausnahmen nicht ordnungsgemäß behandelt werden, wird kein Fehler bei der Kompilierung angezeigt. Das Programm wird jedoch zur Laufzeit vorzeitig beendet.
Alle Unterklassen von RunTimeException und Error sind nicht aktivierte Ausnahmen.
Hypothetisches Beispiel - Angenommen, Sie befinden sich in Ihrer Prüfungshalle, aber Ihre Schule hatte irgendwie einen Brandunfall (dh zur Laufzeit), bei dem Sie zu diesem Zeitpunkt nichts tun können, aber vorher Vorsichtsmaßnahmen getroffen werden können (Kompilierungszeit).
quelle
Alle Ausnahmen müssen überprüft werden.
Ungeprüfte Ausnahmen sind uneingeschränkte Gotos. Und uneingeschränkte Gotos gelten als eine schlechte Sache.
Nicht aktivierte Ausnahmen unterbrechen die Kapselung. Um sie korrekt zu verarbeiten, müssen alle Funktionen im Aufrufbaum zwischen dem Werfer und dem Catcher bekannt sein, um Fehler zu vermeiden.
Ausnahmen sind Fehler in der Funktion, die sie auslöst, aber keine Fehler in der Funktion, die sie verarbeitet. Der Zweck von Ausnahmen besteht darin, dem Programm eine zweite Chance zu geben, indem die Entscheidung, ob es sich um einen Fehler handelt oder nicht, auf einen anderen Kontext verschoben wird. Nur im anderen Kontext kann die richtige Entscheidung getroffen werden.
quelle