603 Stimmen

Unfangbare ChuckNorrisException

Ist es möglich, einen Codeschnipsel zu konstruieren in Java Das würde eine hypothetische java.lang.ChuckNorrisException uneinholbar?

Denkbar wären zum Beispiel die Verwendung von Abfangjägern oder aspektorientierte Programmierung .

28voto

mirelon Punkte 4676

Jede Ausnahme, die Sie auslösen, muss Throwable erweitern, damit sie immer abgefangen werden kann. Die Antwort ist also nein.

Wenn Sie die Handhabung erschweren wollen, können Sie die Methoden überschreiben getCause(), getMessage() , getStackTrace() , toString() eine andere zu werfen java.lang.ChuckNorrisException .

25voto

Wildfire Punkte 6308

Meine Antwort basiert auf der Idee von @jtahlborn, aber es ist eine voll funktionsfähige Java Programm, das in ein Paket verpackt werden kann JAR Datei und sogar auf Ihrem bevorzugten Anwendungsserver als Teil einer Webanwendung .

Zunächst einmal sollten wir definieren ChuckNorrisException Klasse, damit sie die JVM nicht von Anfang an zum Absturz bringt (Chuck liebt es übrigens, JVMs 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 Expendables Klasse, um sie 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 Main Klasse, um in den 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 dem folgenden Befehl aus:

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

Sie erhalten dann folgende Ausgabe:

before
finally

Kein Wunder - es ist ja auch ein Roundhouse-Kick :)

15voto

Peter Lawrey Punkte 511323

Im Konstruktor könnten Sie einen Thread starten, der wiederholt die originalThread.stop (ChuckNorisException.this)

Der Thread könnte die Ausnahme wiederholt abfangen, würde sie aber immer wieder auslösen, bis er stirbt.

13voto

VolatileDream Punkte 1073

Nein. Alle Ausnahmen in Java müssen die Unterklasse java.lang.Throwable und obwohl es nicht unbedingt eine gute Praxis 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.
}

Siehe die java.lang.Throwable Dokumentation für weitere Informationen.

Wenn Sie versuchen zu vermeiden, dass geprüfte Ausnahmen (solche, die explizit behandelt werden müssen), dann sollten Sie Error oder RuntimeException unterklassifizieren.

9voto

kriegaex Punkte 56700

A

A r !

E

package de.scrum_master.app;

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

A

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

S

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)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X