Gibt es eine Möglichkeit, eine Ausnahme auszulösen, ohne die throws-Deklaration hinzuzufügen?
Lesezeit: 6 Minuten
Jürgen Steinblock
Ich habe folgende Situation.
Ich habe eine Java-Klasse, die von einer anderen Basisklasse erbt und eine Methode überschreibt. Die Basismethode löst keine Ausnahmen aus und hat daher keine throws ... Erklärung.
Jetzt sollte meine eigene Methode in der Lage sein, eine Ausnahme auszulösen, aber ich habe die Wahl zwischen beiden
Schlucken Sie die Ausnahme oder
Fügen Sie eine throws-Deklaration hinzu
Beides ist nicht zufriedenstellend, da das erste die Ausnahme stillschweigend ignorieren würde (ok, ich könnte eine Protokollierung durchführen) und das zweite aufgrund der unterschiedlichen Methodenheader Compilerfehler generieren würde.
public class ChildClass extends BaseClass {
@Override
public void SomeMethod() {
throw new Exception("Something went wrong");
}
}
Orangenhund
Sie können ungeprüfte Ausnahmen auslösen, ohne sie deklarieren zu müssen, wenn Sie das wirklich wollen. Ungeprüfte Ausnahmen verlängern RuntimeException. Throwables, die sich ausdehnen Error sind ebenfalls deaktiviert, sollten aber nur bei völlig unhandhabbaren Problemen (z. B. ungültiger Bytecode oder Speichermangel) verwendet werden.
Als Sonderfall kam Java 8 hinzu UncheckedIOException zum Wickeln und Umwerfen IOException.
Funktioniert großartig, ich muss eine RuntimeException erneut auslösen, da die Ausnahme von einer anderen Methode stammt, aber es funktioniert großartig, danke.
– Jürgen Steinblock
23. Dezember 2010 um 14:42 Uhr
Eng.Fouad
Hier ist ein Trick:
class Utils
{
@SuppressWarnings("unchecked")
private static <T extends Throwable> void throwException(Throwable exception, Object dummy) throws T
{
throw (T) exception;
}
public static void throwException(Throwable exception)
{
Utils.<RuntimeException>throwException(exception, null);
}
}
public class Test
{
public static void main(String[] args)
{
Utils.throwException(new Exception("This is an exception!"));
}
}
Ich frage mich, wie das funktioniert? Ich werde etwas recherchieren, aber haben Sie irgendwelche Ressourcen, die mir helfen können? 🙂
– holmicz
22. November 2016 um 8:24 Uhr
T als RuntimeException abgeleitet. Beantwortet hier stackoverflow.com/questions/41380656/… und hier stackoverflow.com/questions/31316581/…
– gesehenimurugan
29. Dezember 2016 um 13:43 Uhr
Toller Trick! Dieser Trick kann auch auf Lambda-Ausdrücke/-Blöcke angewendet werden, um der SAM-Schnittstelle die Checked-Exception-Methode ohne irgendwelche zuweisen zu können throws Erklärungen.
– JasonMing
29. August 2017 um 8:22 Uhr
hat den zusätzlichen Super-Zusatzbonus, sich nicht mit unsicheren Dingen auseinandersetzen zu müssen.
– lscoughlin
14. März 2020 um 9:51 Uhr
Warum brauchen Sie den Dummy-Parameter? Könnte dies auch ohne die generische Methode funktionieren?
– Kiruahxh
3. August 2020 um 7:22 Uhr
Eine dritte Option besteht darin, die Ausnahmeprüfung abzulehnen (wie es die Standard-API manchmal selbst tun muss) und die geprüfte Ausnahme in eine einzuschließen RuntimeException:
throw new RuntimeException(originalException);
Möglicherweise möchten Sie eine spezifischere Unterklasse von verwenden RuntimeException.
Ich möchte nur eine alternative Antwort hinzufügen, rein als FYI:
Ja, es gibt eine Möglichkeit, eine geprüfte Ausnahme auszulösen, ohne die hinzuzufügen throws Deklaration, indem Sie die sun.misc.Unsafe Klasse. Dies wird in folgendem Blogbeitrag beschrieben:
public void someMethod() {
//throw a checked exception without adding a "throws"
getUnsafe().throwException(new IOException());
}
private Unsafe getUnsafe() {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
return (Unsafe) field.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Dies wird jedoch nicht empfohlen. Es ist besser, eine ungeprüfte Ausnahme einzuschließen, wie in einigen der anderen Antworten beschrieben.
Peter Lawrey
Warum werfen Sie keine ungeprüfte Ausnahme? Dies muss nicht deklariert werden.
Zwei Alternativen sind
Wrap mit einer geprüften Ausnahme mit einer ungeprüften.
Lassen Sie den Compiler nicht wissen, dass Sie eine geprüfte Ausnahme auslösen, z. B. Thread.currentThread().stop(e);
In Java 6 können Sie die Ausnahme erneut auslösen, falls dies der Fall ist final und der Compiler wissen, welche geprüften Ausnahmen Sie möglicherweise abgefangen haben.
In Java 7 können Sie eine Ausnahme erneut auslösen, wenn sie effektiv endgültig ist, dh Sie ändern sie nicht im Code.
Letzteres ist nützlicher, wenn Sie eine Prüfausnahme in Ihrem Code auslösen und in Ihrem aufrufenden Code abfangen, aber die Ebenen dazwischen nichts über die Ausnahme wissen.
Die zweite Methode ist auch interessant. Aber im Moment ist das Umhüllen der Ausnahme genau das, was ich brauche.
@OrangeDog, da Sie dies gelesen haben, können Sie mir sagen, was der Unterschied zwischen der Verwendung von stop() im aktuellen Thread und dem Auslösen einer umschlossenen Ausnahme ist. 😉
– Peter Lawrey
23. Dezember 2010 um 15:56 Uhr
“Die folgende Methode ist verhaltensmäßig identisch mit der Throw-Operation von Java, umgeht jedoch die Versuche des Compilers zu garantieren, dass die aufrufende Methode alle geprüften Ausnahmen deklariert hat, die sie möglicherweise auslöst.” Wie wird die Ausnahme besser verpackt?
– Peter Lawrey
23. Dezember 2010 um 15:58 Uhr
“Durch das Stoppen eines Threads werden alle von ihm gesperrten Monitore entsperrt. Wenn eines der zuvor durch diese Monitore geschützten Objekte in einem inkonsistenten Zustand war, können andere Threads diese Objekte jetzt in einem inkonsistenten Zustand anzeigen. […] Im Gegensatz zu anderen ungeprüften Ausnahmen […] der Benutzer erhält keine Warnung, dass sein Programm beschädigt sein könnte.”
– Orangenhund
23. Dezember 2010 um 21:34 Uhr
Ahmad Al-Kurdi
Ja, es gibt einen Grund, aber es wird überhaupt nicht empfohlen, dass Sie Folgendes verwenden können:
Unsicheres Java-Paket
getUnsafe().throwException(new IOException());
Diese Methode löst eine geprüfte Ausnahme aus, aber Ihr Code muss sie nicht abfangen oder erneut auslösen. Genau wie Laufzeitausnahme.
Die zweite Methode ist auch interessant. Aber im Moment ist das Umhüllen der Ausnahme genau das, was ich brauche.
@OrangeDog, da Sie dies gelesen haben, können Sie mir sagen, was der Unterschied zwischen der Verwendung von stop() im aktuellen Thread und dem Auslösen einer umschlossenen Ausnahme ist. 😉
– Peter Lawrey
23. Dezember 2010 um 15:56 Uhr
“Die folgende Methode ist verhaltensmäßig identisch mit der Throw-Operation von Java, umgeht jedoch die Versuche des Compilers zu garantieren, dass die aufrufende Methode alle geprüften Ausnahmen deklariert hat, die sie möglicherweise auslöst.” Wie wird die Ausnahme besser verpackt?
– Peter Lawrey
23. Dezember 2010 um 15:58 Uhr
“Durch das Stoppen eines Threads werden alle von ihm gesperrten Monitore entsperrt. Wenn eines der zuvor durch diese Monitore geschützten Objekte in einem inkonsistenten Zustand war, können andere Threads diese Objekte jetzt in einem inkonsistenten Zustand anzeigen. […] Im Gegensatz zu anderen ungeprüften Ausnahmen […] der Benutzer erhält keine Warnung, dass sein Programm beschädigt sein könnte.”
– Orangenhund
23. Dezember 2010 um 21:34 Uhr
Jason S
Hier ist ein Beispiel für das Abfangen von geprüften Ausnahmen und das Einschließen in eine ungeprüfte Ausnahme:
public void someMethod() {
try {
doEvil();
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
12573900cookie-checkGibt es eine Möglichkeit, eine Ausnahme auszulösen, ohne die throws-Deklaration hinzuzufügen?yes