Gibt es eine Möglichkeit, eine Ausnahme auszulösen, ohne die throws-Deklaration hinzuzufügen?

Lesezeit: 6 Minuten

Benutzer-Avatar
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");
        }
}

Benutzer-Avatar
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

Benutzer-Avatar
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:

Löst eine geprüfte Ausnahme von einer Methode aus, ohne sie zu deklarieren

Beispielcode:

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.

Benutzer-Avatar
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.

    – Jürgen Steinblock

    23. Dezember 2010 um 14:43 Uhr

  • download.oracle.com/javase/6/docs/technotes/guides/concurrency/…

    – Orangenhund

    23. Dezember 2010 um 14:45 Uhr

  • @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

Benutzer-Avatar
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.

    – Jürgen Steinblock

    23. Dezember 2010 um 14:43 Uhr

  • download.oracle.com/javase/6/docs/technotes/guides/concurrency/…

    – Orangenhund

    23. Dezember 2010 um 14:45 Uhr

  • @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

Benutzer-Avatar
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);
   }
}

1257390cookie-checkGibt es eine Möglichkeit, eine Ausnahme auszulösen, ohne die throws-Deklaration hinzuzufügen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy