web-dev-qa-db-ger.com

Können Konstruktoren in Java Ausnahmen auslösen?

Dürfen Konstrukteure Ausnahmen auslösen?

220
Mahmoud Hossam

Ja, Konstruktoren können Ausnahmen auslösen. In der Regel bedeutet dies, dass das neue Objekt sofort zur Garbage Collection berechtigt ist (obwohl es möglicherweise für einige Zeit nicht gesammelt wird). Es ist jedoch möglich, dass das "halbkonstruierte" Objekt erhalten bleibt, wenn es zuvor im Konstruktor sichtbar gemacht wurde (z. B. durch Zuweisen eines statischen Felds oder Hinzufügen zu einer Auflistung).

Beachten Sie beim Auslösen von Ausnahmen im Konstruktor Folgendes: Da der Aufrufer (normalerweise) keine Möglichkeit hat, das neue Objekt zu verwenden, sollte der Konstruktor darauf achten, nicht verwaltete Ressourcen (Dateihandles usw.) nicht zu beschaffen und dann eine Ausnahme auszulösen ohne sie freizugeben. Wenn der Konstruktor beispielsweise versucht, einen FileInputStream und einen FileOutputStream zu öffnen und der erste erfolgreich ist, der zweite jedoch fehlschlägt, sollten Sie versuchen, den ersten Stream zu schließen. Dies wird schwieriger, wenn es sich um einen Unterklassenkonstruktor handelt, der natürlich die Ausnahme auslöst ... alles wird ein bisschen knifflig. Es ist nicht sehr oft ein Problem, aber es lohnt sich, darüber nachzudenken.

348
Jon Skeet

Ja, sie können Ausnahmen werfen. In diesem Fall werden sie nur teilweise initialisiert und, falls sie nicht endgültig sind, einem Angriff ausgesetzt.

Das Folgende stammt aus den Secure Coding Guidelines 2. .

Auf teilweise initialisierte Instanzen einer nicht finalen Klasse kann über einen Finalizer-Angriff zugegriffen werden. Der Angreifer überschreibt die geschützte Finalisierungsmethode in einer Unterklasse und versucht, eine neue Instanz dieser Unterklasse zu erstellen. Dieser Versuch schlägt fehl (im obigen Beispiel löst die SecurityManager-Prüfung im Konstruktor von ClassLoader eine Sicherheitsausnahme aus), der Angreifer ignoriert jedoch einfach alle Ausnahmen und wartet, bis die virtuelle Maschine die Finalisierung für das teilweise initialisierte Objekt durchgeführt hat. In diesem Fall wird die Implementierung der böswilligen Finalisierungsmethode aufgerufen, die dem Angreifer Zugriff auf diese Methode gewährt und einen Verweis auf das zu finalisierende Objekt enthält. Obwohl das Objekt nur teilweise initialisiert ist, kann der Angreifer dennoch Methoden darauf aufrufen (wodurch die SecurityManager-Prüfung umgangen wird).

78
Billy Bob Bain

Absolut.

Wenn der Konstruktor keine gültige Eingabe erhält oder das Objekt nicht auf gültige Weise erstellen kann, hat er keine andere Option, als eine Ausnahme auszulösen und den Aufrufer zu benachrichtigen.

33
Yuval

Ja, es kann eine Ausnahme auslösen und Sie können dies auch in der Signatur des Konstruktors deklarieren, wie im folgenden Beispiel gezeigt:

public class ConstructorTest
{
    public ConstructorTest() throws InterruptedException
    {
        System.out.println("Preparing object....");
        Thread.sleep(1000);
        System.out.println("Object ready");
    }

    public static void main(String ... args)
    {
        try
        {
            ConstructorTest test = new ConstructorTest();
        }
        catch (InterruptedException e)
        {
            System.out.println("Got interrupted...");
        }
    }
}
14
V_Singh

Ja, Konstruktoren dürfen Ausnahmen auslösen.

Seien Sie jedoch sehr weise bei der Auswahl der Ausnahmen, die überprüft oder deaktiviert werden sollen. Nicht aktivierte Ausnahmen sind grundsätzlich Unterklassen von RuntimeException.

In fast allen Fällen (ich konnte keine Ausnahme für diesen Fall finden) müssen Sie eine aktivierte Ausnahme auslösen. Der Grund dafür ist, dass ungeprüfte Ausnahmen (wie NullPointerException) normalerweise auf Programmierfehler zurückzuführen sind (z. B. Eingaben nicht ausreichend validieren).

Der Vorteil, den eine aktivierte Ausnahme bietet, besteht darin, dass der Programmierer gezwungen ist, die Ausnahme in seinem Instantiierungscode abzufangen, und dadurch erkennt, dass die Objektinstanz möglicherweise nicht erstellt werden kann. Natürlich wird nur eine Codeüberprüfung die schlechte Programmierpraxis auffangen, eine Ausnahme zu schlucken.

11
Vineet Reynolds

Ja.

Konstruktoren sind nichts anderes als spezielle Methoden und können wie jede andere Methode Ausnahmen auslösen.

7
Isaac