Ist es möglich , einen Codeausschnitt in Java zujava.lang.ChuckNorrisException
erstellen , der eine Hypothese unauffindbar macht?
Gedanken, die mir in den Sinn kamen, verwenden zum Beispiel Interceptors oder aspektorientierte Programmierung .
java
exception
exception-handling
aop
Max Charas
quelle
quelle
finalize()
?Antworten:
Ich habe nicht versucht, damit ich weiß nicht , ob der JVM so etwas wie dies beschränken würde, aber vielleicht könnten Sie Code kompilieren , die werfen
ChuckNorrisException
, sondern zur Laufzeit eine Klassendefinition zur Verfügung stelle vonChuckNorrisException
denen Throwable nicht erstreckt .AKTUALISIEREN:
Es funktioniert nicht. Es wird ein Überprüfungsfehler generiert:
UPDATE 2:
Tatsächlich können Sie dies zum Laufen bringen, wenn Sie den Bytecode-Verifizierer deaktivieren! (
-Xverify:none
)UPDATE 3:
Für diejenigen, die von zu Hause aus folgen, ist hier das vollständige Skript:
Erstellen Sie die folgenden Klassen:
Klassen kompilieren:
Lauf:
Kommentieren Sie "erweitert RuntimeException" aus und kompilieren Sie
ChuckNorrisException.java
nur neu :Lauf:
Ohne Überprüfung ausführen:
quelle
Object
stattThrowable
, dann? (Der Compiler lässt es nicht zu, aber da wir den Verifizierer bereits deaktiviert haben, könnte man vielleicht den Bytecode hacken, um dies zu tun.)Nachdem ich darüber nachgedacht habe, habe ich erfolgreich eine nicht abfangbare Ausnahme erstellt. Ich habe es
JulesWinnfield
jedoch lieber als Chuck genannt, weil es eine Ausnahme ist, die Pilzwolken legt. Außerdem ist es vielleicht nicht genau das, was Sie sich vorgestellt haben, aber es kann sicherlich nicht gefangen werden. Beobachten:Et voila! Nicht erfasste Ausnahme.
Ausgabe:
Wenn ich etwas mehr Zeit habe, werde ich sehen, ob ich mir auch nichts anderes einfallen lassen kann.
Überprüfen Sie dies auch:
Verursacht einen Stapelüberlauf - auch hier bleiben Ausnahmen nicht erfasst.
quelle
JulesWinfield
? Wird das System nicht kreischend zum Stillstand kommen, bevor es geworfen wird?throw new Whatever()
besteht eigentlich aus zwei Teilen:Whatever it = new Whatever(); throw it;
und das System stirbt, bevor es den zweiten Teil erreicht.class cn extends exception{private cn(){}}
Mit einer solchen Ausnahme wäre es natürlich obligatorisch, ein
System.exit(Integer.MIN_VALUE);
vom Konstruktor zu verwenden, da dies passieren würde, wenn Sie eine solche Ausnahme auslösen würden;)quelle
while(true){}
anstelle von verwendenSystem.exit()
.System.exit()
Arbeiten verhindern , indem Sie einen Sicherheitsmanager installieren, der dies nicht zulässt. das würde den Konstruktor in eine andere Ausnahme (SecurityException) verwandeln, die abgefangen werden könnte.Jeder Code kann Throwable fangen. Also nein, jede Ausnahme, die Sie erstellen, wird eine Unterklasse von Throwable sein und kann abgefangen werden.
quelle
hang
selbst versuchen, ChuckNorrisException zu fangen: P(Zugegeben, technisch gesehen wird diese Ausnahme nie wirklich ausgelöst, aber eine richtige
ChuckNorrisException
kann nicht ausgelöst werden - sie wirft Sie zuerst.)quelle
Jede Ausnahme, die Sie auslösen, muss Throwable erweitern, damit sie immer abgefangen werden kann. Die Antwort lautet also nein.
Wenn Sie es schwierig zu handhaben machen möchten, können Sie außer Kraft setzen Methoden
getCause(), getMessage()
,getStackTrace()
, einetoString()
andere zu werfenjava.lang.ChuckNorrisException
.quelle
catch(Throwable t)
, speichert es nur in Variablen, so dass meine Vorschläge nur im nächsten Block gelten, wenn Benutzer mit der Ausnahme fertig werden wollenMeine Antwort basiert auf der Idee von @ jtahlborn, aber es ist ein voll funktionsfähiges Java- Programm, das in eine JAR- Datei gepackt und sogar als Teil einer Webanwendung auf Ihrem bevorzugten Anwendungsserver bereitgestellt werden kann .
Definieren wir zunächst die
ChuckNorrisException
Klasse, damit die JVM nicht von Anfang an abstürzt (Chuck liebt es wirklich, JVMs übrigens zum Absturz zu bringen :)Jetzt geht
Expendables
Klasse, um es zu konstruieren:Und schließlich die
Main
Klasse, um einen Hintern zu treten:Kompilieren Sie es und führen Sie es mit folgendem Befehl aus:
Sie erhalten folgende Ausgabe:
Kein Wunder - es ist doch ein Roundhouse-Kick :)
quelle
Im Konstruktor können Sie einen Thread starten, der wiederholt aufruft
originalThread.stop (ChuckNorisException.this)
Der Thread konnte die Ausnahme wiederholt abfangen, warf sie jedoch weiter, bis sie stirbt.
quelle
Nein. Alle Ausnahmen in Java müssen Unterklassen sein
java.lang.Throwable
. Auch wenn dies möglicherweise keine gute Vorgehensweise ist, können Sie jede Art von Ausnahme wie folgt abfangen:Weitere Informationen finden Sie in der Dokumentation zu java.lang.Throwable .
Wenn Sie versuchen, aktivierte Ausnahmen zu vermeiden (solche, die explizit behandelt werden müssen), sollten Sie Error oder RuntimeException in Unterklassen unterteilen.
quelle
Eigentlich ist die akzeptierte Antwort nicht so schön, weil Java ohne Überprüfung ausgeführt werden muss, dh der Code würde unter normalen Umständen nicht funktionieren.
Aspekt zur Rettung für die echte Lösung !
Ausnahmeklasse:
Aspekt:
Beispielanwendung:
Ausgabe:
quelle
Eine Variante des Themas ist die überraschende Tatsache, dass Sie nicht deklarierte geprüfte Ausnahmen aus Java-Code auslösen können. Da es nicht in der Methodensignatur deklariert ist, lässt der Compiler Sie die Ausnahme selbst nicht abfangen, obwohl Sie sie als java.lang.Exception abfangen können.
Hier ist eine Hilfsklasse, mit der Sie alles werfen können, ob deklariert oder nicht:
throw SneakyThrow.sneak(new ChuckNorrisException());
Löst jetzt eine ChuckNorrisException aus, aber der Compiler beschwert sichInformationen zum Abfangen einer Ausnahme, die nicht ausgelöst wird, wenn ChuckNorrisException eine aktivierte Ausnahme ist.
quelle
Das einzige
ChuckNorrisException
s in Java sollteOutOfMemoryError
und seinStackOverflowError
.Sie können sie tatsächlich "fangen", indem Sie a
catch(OutOfMemoryError ex)
ausführen, falls die Ausnahme ausgelöst wird, dieser Block die Ausnahme jedoch automatisch an den Aufrufer zurückgibt.Ich denke nicht, dass
public class ChuckNorrisError extends Error
das den Trick macht, aber Sie könnten es versuchen. Ich habe keine Dokumentation zur Erweiterung gefundenError
quelle
Is it possible to construct a snippet of code in java that would make a hypothetical java.lang.ChuckNorrisException uncatchable?
Ja, und hier ist die Antwort: Entwerfen Sie Ihre
java.lang.ChuckNorrisException
so, dass es keine Instanz von istjava.lang.Throwable
. Warum? Ein nicht werfbares Objekt ist per Definition nicht fangbar, da Sie niemals etwas fangen können, das niemals geworfen werden kann.quelle
java.lang.ChuckNorrisException
eine Ausnahme sein müssen, geschweige denn wegwerfbarSie können ChuckNorris intern oder privat halten und ihn einkapseln oder schlucken ...
try { doChuckAction(); } catch(ChuckNorrisException cne) { /*do something else*/ }
quelle
Zwei grundlegende Probleme bei der Ausnahmebehandlung in Java bestehen darin, dass der Typ einer Ausnahme verwendet wird, um anzugeben, ob darauf basierende Maßnahmen ergriffen werden sollen, und dass angenommen wird, dass alles, was auf der Grundlage einer Ausnahme Maßnahmen ergreift (dh "fangen"), behoben wird die zugrunde liegende Bedingung. Es wäre nützlich, ein Mittel zu haben, mit dem ein Ausnahmeobjekt entscheiden könnte, welche Handler ausgeführt werden sollen, und ob die Handler, die bisher ausgeführt wurden, die Dinge so weit aufgeräumt haben, dass die vorliegende Methode ihre Ausgangsbedingungen erfüllt. Während dies verwendet werden könnte, um "nicht abfangbare" Ausnahmen zu machen, wären zwei größere Verwendungszwecke, (1) Ausnahmen zu machen, die nur dann behandelt werden, wenn sie von Code abgefangen werden, der tatsächlich weiß, wie man mit ihnen umgeht.
finally
FooException
finally
Blocks während des Abwickelns von aBarException
sollten beide Ausnahmen den Aufrufstapel weitergeben. beide sollten fangbar sein, aber das Abwickeln sollte fortgesetzt werden, bis beide gefangen wurden). Leider glaube ich nicht, dass es eine Möglichkeit gibt, vorhandenen Code für die Ausnahmebehandlung so zu gestalten, ohne dass Probleme auftreten.quelle
finally
Block von einer früheren Ausnahme bereinigt wird, ist es durchaus möglich, dass eine Ausnahme in Abwesenheit der anderen etwas ist, das der Code voraussichtlich verarbeiten und fortsetzen wird. aber es wäre schlecht, mit dem einen umzugehen und den anderen zu ignorieren. Es gibt jedoch keinen Mechanismus, um eine zusammengesetzte Ausnahme zu erzeugen, die beide Handler verarbeiten würden.Foo
, zwischen einer Ausnahme, die sichFoo
entweder selbst geworfen hat oder absichtlich so tun möchte, als hätte sie sich selbst geworfen, von einer Ausnahme unterscheiden kann, dieFoo
nicht erwartet hatte, dass sie auftrat, als sie auftrat eine andere Methode aufrufen. Darum sollte der Begriff "geprüfte" Ausnahmen "gehen".Es ist leicht möglich, eine nicht erfasste Ausnahme für den aktuellen Thread zu simulieren. Dies löst das reguläre Verhalten einer nicht erfassten Ausnahme aus und erledigt die Aufgabe somit semantisch. Die Ausführung des aktuellen Threads wird jedoch nicht unbedingt gestoppt, da tatsächlich keine Ausnahme ausgelöst wird.
Dies ist tatsächlich in (sehr seltenen) Situationen nützlich, beispielsweise wenn eine ordnungsgemäße
Error
Behandlung erforderlich ist, die Methode jedoch von einem Framework aus aufgerufen wird, das alle abfängt (und verwirft)Throwable
.quelle
Rufen Sie System.exit (1) in der auf
finalize
und werfen Sie einfach eine Kopie der Ausnahme von allen anderen Methoden, damit das Programm beendet wird.quelle