Nicht fangbare ChuckNorrisException

596

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 .

Max Charas
quelle
2
mit dem Vorschlag von dem darin enthaltenen Link @jschoen (disable der Bytecode Verifier) Sie können etwas werfen , die Throwable nicht verlängern! beschrieben in meiner Antwort unten.
Jtahlborn
4
Dieser Auszug aus der Antwort von aioobe fasst die Frage @jschoen gut verknüpft zusammen: "Das heißt, Ihre Frage kann interpretiert werden als 'Wenn eine JVM von der Spezifikation abweicht, kann sie seltsame Dinge wie das Werfen von Primitiven tun' und die Antwort ist natürlich: Ja."
Dan spielt am Feuer
2
@Max - Können Sie die praktischen Anwendungen dafür näher erläutern?
Vineet Bhatia
3
Wie wäre es mit einer Ausnahme, die sich auf die neu wirft finalize()?
Lie Ryan

Antworten:

314

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 von ChuckNorrisExceptiondenen Throwable nicht erstreckt .

AKTUALISIEREN:

Es funktioniert nicht. Es wird ein Überprüfungsfehler generiert:

Exception in thread "main" java.lang.VerifyError: (class: TestThrow, method: ma\
in signature: ([Ljava/lang/String;)V) Can only throw Throwable objects
Could not find the main class: TestThrow.  Program will exit.

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:

public class ChuckNorrisException
    extends RuntimeException // <- Comment out this line on second compilation
{
    public ChuckNorrisException() { }
}

public class TestVillain {
    public static void main(String[] args) {
        try {
            throw new ChuckNorrisException();
        }
        catch(Throwable t) {
            System.out.println("Gotcha!");
        }
        finally {
            System.out.println("The end.");
        }
    }
}

Klassen kompilieren:

javac -cp . TestVillain.java ChuckNorrisException.java

Lauf:

java -cp . TestVillain
Gotcha!
The end.

Kommentieren Sie "erweitert RuntimeException" aus und kompilieren Sie ChuckNorrisException.javanur neu :

javac -cp . ChuckNorrisException.java

Lauf:

java -cp . TestVillain
Exception in thread "main" java.lang.VerifyError: (class: TestVillain, method: main signature: ([Ljava/lang/String;)V) Can only throw Throwable objects
Could not find the main class: TestVillain.  Program will exit.

Ohne Überprüfung ausführen:

java -Xverify:none -cp . TestVillain
The end.
Exception in thread "main"
jtahlborn
quelle
18
OK, so was ist, wenn Sie fangen Objectstatt Throwable, 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.)
Ilmari Karonen
11
Laut Was können Sie in Java werfen? Sie können immer noch Dinge fangen, die nicht erweiterbar sind, aber das Werfen und Fangen ist undefiniertes Verhalten.
VolatileDream
8
@dzieciou Sie können zusammen wahr sein. Möglicherweise können Sie sie mit Ihrer Version der Java-Umgebung in Ihrer spezifischen Version Ihres Betriebssystems auf Ihrem Prozessortyp abfangen. Wenn im Standard nicht angegeben ist, ob es abgefangen werden kann, wird es als undefiniertes Verhalten bezeichnet, da andere Java-Implementierungen es möglicherweise nicht abfangbar machen.
heinrich5991
2
Hmmph. Ich hatte gehofft, dass Sie für 176 Upvotes einen JNI-Code geschrieben haben, der den gesamten Aufrufstapel mit Affen-Patches verbindet, um Ihre Ausnahme erneut auszulösen (natürlich vom Ctor aufgerufen).
kdgregory
3
Wenn Sie all dies tun, ist es auch eine großartige Idee, auf einem Bein zu stehen, Ihren Kopf zu streicheln und Ihren Bauch zu reiben, während Sie Dixie pfeifen ...;);)
Glen Best
120

Nachdem ich darüber nachgedacht habe, habe ich erfolgreich eine nicht abfangbare Ausnahme erstellt. Ich habe es JulesWinnfieldjedoch 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:

public static class JulesWinnfield extends Exception
{
    JulesWinnfield()
    {
        System.err.println("Say 'What' again! I dare you! I double dare you!");
        System.exit(25-17); // And you shall know I am the LORD
    }
}


public static void main(String[] args)
{       
    try
    {
        throw new JulesWinnfield();
    } 
    catch(JulesWinnfield jw)
    {
        System.out.println("There's a word for that Jules - a bum");
    }
}

Et voila! Nicht erfasste Ausnahme.

Ausgabe:

Lauf:

Sag noch mal "was! Du traust dich ja nicht! Ich wage dich doppelt!

Java Ergebnis: 8

ERFOLGREICH BAUEN (Gesamtzeit: 0 Sekunden)

Wenn ich etwas mehr Zeit habe, werde ich sehen, ob ich mir auch nichts anderes einfallen lassen kann.

Überprüfen Sie dies auch:

public static class JulesWinnfield extends Exception
{
    JulesWinnfield() throws JulesWinnfield, VincentVega
    {
        throw new VincentVega();
    }
}

public static class VincentVega extends Exception
{
    VincentVega() throws JulesWinnfield, VincentVega
    {
        throw new JulesWinnfield();
    }
}


public static void main(String[] args) throws VincentVega
{

    try
    {
        throw new JulesWinnfield();
    }
    catch(JulesWinnfield jw)
    {

    }
    catch(VincentVega vv)
    {

    }
}

Verursacht einen Stapelüberlauf - auch hier bleiben Ausnahmen nicht erfasst.

MikeTheLiar
quelle
32
+1 für die Verwendung von Stapelüberlauf in Ihrer Antwort. Nur ein Scherz, wirklich gute Antwort.
Josiah
7
Eine ordnungsgemäße "nicht abfangbare Ausnahme" würde sicherstellen, dass alle umschließenden Endblöcke ohne dazwischenliegende Fänge ausgeführt werden. Das Töten des Systems löst keine Ausnahme aus - es tötet nur das System.
Supercat
4
Wie "wirft" man das JulesWinfield? Wird das System nicht kreischend zum Stillstand kommen, bevor es geworfen wird?
Supercat
6
@mikeTheLiar: Das System wird während des Konstruktors beendet, nicht wahr? Die Aussage throw new Whatever()besteht eigentlich aus zwei Teilen: Whatever it = new Whatever(); throw it;und das System stirbt, bevor es den zweiten Teil erreicht.
Supercat
5
@mikeTheLiar Sie können Jules oder Vincent tatsächlich ganz leicht fangen ... wenn Sie es schaffen, es zu werfen. Es ist einfach, eine Ausnahme zu erstellen, die Sie nicht auslösen können:class cn extends exception{private cn(){}}
John Dvorak
85

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;)

Korgen
quelle
32
+1; IMO ist dies die einzig mögliche Lösung. Eine nicht abfangbare Ausnahme ist, das Programm zu beenden ...
home
7
Nein, es wäre nicht das, was passiert, wenn Sie eine solche Ausnahme auslösen. Eine nicht erfasste Ausnahme beendet einen einzelnen Thread, beendet die JVM nicht, in einigen Kontexten verursacht System.exit selbst sogar eine SecurityException - nicht jeder Code darf ein Programm herunterfahren.
Josefx
3
Sie können while(true){}anstelle von verwenden System.exit().
Piotr Praszmo
2
Sie können das 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.
Jtahlborn
5
Umm, technisch Sie nie warf eine Ausnahme. Sie haben noch nicht einmal das Objekt zum Werfen konstruiert!
Thomas Eding
46

Jeder Code kann Throwable fangen. Also nein, jede Ausnahme, die Sie erstellen, wird eine Unterklasse von Throwable sein und kann abgefangen werden.

Nathan Hughes
quelle
11
Throwable würde hangselbst versuchen, ChuckNorrisException zu fangen: P
PermGenError
35
public class ChuckNorrisException extends Exception {
    public ChuckNorrisException() {
        System.exit(1);
    }
}

(Zugegeben, technisch gesehen wird diese Ausnahme nie wirklich ausgelöst, aber eine richtige ChuckNorrisExceptionkann nicht ausgelöst werden - sie wirft Sie zuerst.)

flauschige
quelle
4
Ein Kollege von mir hatte vorgeschlagen, 'für (;;) {}' zu bleiben, da er der Meinung war, dass ein Aufruf von 'System.exit (1)' eine Sicherheitsausnahme auslösen könnte. Ich stimme diesem für Kreativität zu!
Phil Street
Ich stimme dem Ende Ihrer Antwort zu. Leg dich niemals mit ChuckNorris an, Exception oder nicht.
Benj
28

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(), eine toString()andere zu werfen java.lang.ChuckNorrisException.

Mirelon
quelle
2
Hmm, catch (Throwable t) ruft irgendwelche Methoden auf oder mutiert das Objekt auf andere Weise? Es kann möglich sein, dass eine catch-Klausel eine Ausnahme auslöst, die dies unmöglich macht.
Colton
1
Ich denke 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 wollen
mirelon
24

Meine 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 ChuckNorrisExceptionKlasse, damit die JVM nicht von Anfang an abstürzt (Chuck liebt es wirklich, JVMs übrigens zum Absturz zu bringen :)

package chuck;

import java.io.PrintStream;
import java.io.PrintWriter;

public class ChuckNorrisException extends Exception {

    public ChuckNorrisException() {
    }

    @Override
    public Throwable getCause() {
        return null;
    }

    @Override
    public String getMessage() {
        return toString();
    }

    @Override
    public void printStackTrace(PrintWriter s) {
        super.printStackTrace(s);
    }

    @Override
    public void printStackTrace(PrintStream s) {
        super.printStackTrace(s);
    }
}

Jetzt geht ExpendablesKlasse, um es zu konstruieren:

package chuck;

import javassist.*;

public class Expendables {

    private static Class clz;

    public static ChuckNorrisException getChuck() {
        try {
            if (clz == null) {
                ClassPool pool = ClassPool.getDefault();
                CtClass cc = pool.get("chuck.ChuckNorrisException");
                cc.setSuperclass(pool.get("java.lang.Object"));
                clz = cc.toClass();
            }
            return (ChuckNorrisException)clz.newInstance();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}

Und schließlich die MainKlasse, um einen Hintern zu treten:

package chuck;

public class Main {

    public void roundhouseKick() throws Exception {
        throw Expendables.getChuck();
    }

    public void foo() {
        try {
            roundhouseKick();
        } catch (Throwable ex) {
            System.out.println("Caught " + ex.toString());
        }
    }

    public static void main(String[] args) {
        try {
            System.out.println("before");
            new Main().foo();
            System.out.println("after");
        } finally {
            System.out.println("finally");
        }
    }
}

Kompilieren Sie es und führen Sie es mit folgendem Befehl aus:

java -Xverify:none -cp .:<path_to_javassist-3.9.0.GA.jar> chuck.Main

Sie erhalten folgende Ausgabe:

before
finally

Kein Wunder - es ist doch ein Roundhouse-Kick :)

Lauffeuer
quelle
Sehr schön! Ich habe selbst nicht viel mit der Manipulation von Klassendefinitionen gemacht. Benötigen Sie noch das "verify: none" in der Befehlszeile?
Jtahlborn
@jtahlborn Ja, der Versuch, ein Objekt zu werfen, das nicht von Throwable abstammt, schlägt fehl, ohne "verify: none".
Wildfire
Oh, ich hatte den Eindruck, dass dies irgendwie um diese Einschränkung herum kam. Wie unterscheidet sich das von meiner Antwort?
Jtahlborn
2
Der Hauptunterschied ist, dass es Java-Code ohne Hacking zur Kompilierungszeit funktioniert
Wildfire
15

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.

Peter Lawrey
quelle
13

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:

try {
    //Stuff
} catch ( Throwable T ){
    //Doesn't matter what it was, I caught it.
}

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.

VolatileDream
quelle
9

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:

package de.scrum_master.app;

public class ChuckNorrisException extends RuntimeException {
    public ChuckNorrisException(String message) {
        super(message);
    }
}

Aspekt:

package de.scrum_master.aspect;

import de.scrum_master.app.ChuckNorrisException;

public aspect ChuckNorrisAspect {
    before(ChuckNorrisException chuck) : handler(*) && args(chuck) {
        System.out.println("Somebody is trying to catch Chuck Norris - LOL!");
        throw chuck;
    }
}

Beispielanwendung:

package de.scrum_master.app;

public class Application {
    public static void main(String[] args) {
        catchAllMethod();
    }

    private static void catchAllMethod() {
        try {
            exceptionThrowingMethod();
        }
        catch (Throwable t) {
            System.out.println("Gotcha, " + t.getClass().getSimpleName() + "!");
        }
    }

    private static void exceptionThrowingMethod() {
        throw new ChuckNorrisException("Catch me if you can!");
    }
}

Ausgabe:

Somebody is trying to catch Chuck Norris - LOL!
Exception in thread "main" de.scrum_master.app.ChuckNorrisException: Catch me if you can!
    at de.scrum_master.app.Application.exceptionThrowingMethod(Application.java:18)
    at de.scrum_master.app.Application.catchAllMethod(Application.java:10)
    at de.scrum_master.app.Application.main(Application.java:5)
Kriegaex
quelle
8

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:

public class SneakyThrow {
  public static RuntimeException sneak(Throwable t) {
    throw SneakyThrow.<RuntimeException> throwGivenThrowable(t);
  }

  private static <T extends Throwable> RuntimeException throwGivenThrowable(Throwable t) throws T {
    throw (T) t;
  }
}

throw SneakyThrow.sneak(new ChuckNorrisException());Löst jetzt eine ChuckNorrisException aus, aber der Compiler beschwert sich

try {
  throw SneakyThrow.sneak(new ChuckNorrisException());
} catch (ChuckNorrisException e) {
}

Informationen zum Abfangen einer Ausnahme, die nicht ausgelöst wird, wenn ChuckNorrisException eine aktivierte Ausnahme ist.

Hans-Peter Störr
quelle
6

Das einzige ChuckNorrisExceptions in Java sollte OutOfMemoryErrorund sein StackOverflowError.

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 Errordas den Trick macht, aber Sie könnten es versuchen. Ich habe keine Dokumentation zur Erweiterung gefundenError

usr-local-ΕΨΗΕΛΩΝ
quelle
2
Der Fehler erstreckt sich immer noch auf Throwable, sodass kein Abfangen verhindert werden kann. Das ist beabsichtigt durch die Java-Sprache.
JasonM1
1
@ JasonM1 Ich glaube nicht, dass das OP nach einer tatsächlich "nicht abfangbaren" Ausnahme gefragt hat, und ich meinte, dass sich der Fehler auch dann ausbreitet, wenn Sie ihn abfangen. Also, jeder Throwable ist fangbar, aber diese beiden werden sich irgendwann verbreiten, egal was Sie tun
usr-local-ΕΨΗΕΛΩΝ
Um knifflig zu sein, könnte ChuckNorrisException Throwable direkt erweitern, dann wäre es weder Exception noch Error!
JasonM1
4
Der Fehler verbreitet sich nicht, selbst wenn Sie ihn abfangen. Ich bin mir nicht sicher, woher Sie diese Idee haben.
Jtahlborn
3
Ich denke, Sie sind sehr verwirrt über Erros, es sind normale Ausnahmen wie alles, was Throwable oder sogar Throwable selbst erweitert.
Bests
6

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.ChuckNorrisExceptionso, dass es keine Instanz von ist java.lang.Throwable. Warum? Ein nicht werfbares Objekt ist per Definition nicht fangbar, da Sie niemals etwas fangen können, das niemals geworfen werden kann.

Thomas Eding
quelle
2
Aber dann ist es keine Ausnahme.
Dolbi
8
@ Dolbi: Ich kann keinen Platz in der Frage des OP finden, dass Staaten java.lang.ChuckNorrisExceptioneine Ausnahme sein müssen, geschweige denn wegwerfbar
Thomas Eding
1
Ich denke, es ist nicht angegeben, aber es ist impliziert. Sie sind Mathematiker :-), nicht wahr?
Dolbi
3

Sie können ChuckNorris intern oder privat halten und ihn einkapseln oder schlucken ...

try { doChuckAction(); } catch(ChuckNorrisException cne) { /*do something else*/ }

Jay
quelle
7
Ich glaube nicht, dass die Idee war, es zu fangen. Ich denke, die Idee ist zu verhindern , dass es gefangen wird.
Patrick Roberts
Korrigieren Sie mich, wenn ich falsch liege, aber wenn Sie es intern machen, können Sie es nicht ohne Reflexion erreichen.
Jay
5
Ja, aber solange Sie Exception oder Throwable abfangen können, ist die Sichtbarkeit des tatsächlichen Typs irrelevant.
KeithS
3

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.finallyFooExceptionfinally Blocks während des Abwickelns von a BarExceptionsollten 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.

Superkatze
quelle
Eine interessante Idee, aber ich glaube nicht, dass der Low-Level-Code wissen würde, was eine bestimmte Ausnahme für den Anrufer "bedeutet". Daher denke ich nicht, dass es für den Werfer jemals Sinn machen würde, zu entscheiden, welche Handler ausgeführt werden sollen.
Jtahlborn
@jtahlborn: Im Moment entscheidet der Werfer über die Auswahl des Ausnahmetyps, welche Ausnahmebehandlungsroutinen ausgeführt werden sollen. Dies macht es so gut wie unmöglich, einige Szenarien sauber zu handhaben. Unter anderem: (1) Wenn eine Ausnahme auftritt, während ein finallyBlock 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.
Supercat
@jtahlborn: Außerdem ist es sehr schwierig zuzulassen, dass Ausnahmen, die in Rückrufen auftreten, von der äußeren Anwendungsschicht behandelt werden. Wenn die Ausnahme des Rückrufs in einen anderen Ausnahmetyp eingeschlossen ist, kann der Typ der Rückrufausnahme in der äußeren Ebene nicht verwendet werden, um zu entscheiden, ob sie abgefangen werden soll. Wenn es nicht verpackt ist, kann eine "versehentliche" Ausnahme auf mittlerer Ebene mit einer Ausnahme verwechselt werden, die im Rückruf auftritt. Wenn einem umschlossenen Ausnahmeobjekt mitgeteilt wurde, wann es an die äußere Anwendungsschicht übergeben wurde, kann es beginnen, auf die Typen der umschlossenen Ausnahmen zu antworten.
Supercat
Ich habe nicht über Ihre anderen Punkte gestritten, sondern nur über die Aussage über das Ausnahmeobjekt, das entscheidet, welche Handler ausgeführt werden. Bis zu einem gewissen Grad tun Ausnahmetypen dies bereits, aber es hört sich so an, als wollten Sie etwas Dynamischeres, mit dem ich nicht einverstanden war. Ich denke, Ihr Hauptargument (das Sie seitwärts stellen) ist es, so viele Informationen wie möglich unten zu erfassen und die oberen Ebenen all diese Informationen sehen und damit arbeiten zu lassen . In diesem allgemeinen Punkt stimme ich Ihnen zu, aber der Teufel steckt im Detail / in der Umsetzung.
Jtahlborn
@jtahlborn: Ich wollte nicht, dass die virtuellen Methoden etwas besonders "Dynamisches" implementieren, sondern im Wesentlichen sagen: "Gibt es eine Bedingung des angegebenen Typs, auf die reagiert werden sollte?". Eine Sache, die ich jedoch vergessen habe zu erwähnen, ist, dass es ein Mittel geben sollte, mit dem Code, der aufruft Foo, zwischen einer Ausnahme, die sich Fooentweder selbst geworfen hat oder absichtlich so tun möchte, als hätte sie sich selbst geworfen, von einer Ausnahme unterscheiden kann, die Foonicht erwartet hatte, dass sie auftrat, als sie auftrat eine andere Methode aufrufen. Darum sollte der Begriff "geprüfte" Ausnahmen "gehen".
Supercat
1

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.

Throwable exception = /* ... */;
Thread currentThread = Thread.currentThread();
Thread.UncaughtExceptionHandler uncaughtExceptionHandler =
    currentThread.getUncaughtExceptionHandler();
uncaughtExceptionHandler.uncaughtException(currentThread, exception);
// May be reachable, depending on the uncaught exception handler.

Dies ist tatsächlich in (sehr seltenen) Situationen nützlich, beispielsweise wenn eine ordnungsgemäße ErrorBehandlung erforderlich ist, die Methode jedoch von einem Framework aus aufgerufen wird, das alle abfängt (und verwirft) Throwable.

dst
quelle
0

Rufen Sie System.exit (1) in der auf finalizeund werfen Sie einfach eine Kopie der Ausnahme von allen anderen Methoden, damit das Programm beendet wird.

Demi
quelle