2016-03-05 8 views
8

Rozważ prosty przykład w Javie poniżej. Co się stanie, jeśli utworzę obiekt dzwoniąc pod numer new B(0)? Najpierw obiekt typu B w pamięci. Następnie wyrażenie 1/n spowoduje zgłoszenie wyjątku. Ale utworzony obiekt nigdy nie zostanie sfinalizowany zgodnie ze specyfikacją Java (§12.6.1) poniżej. Czy otrzymujemy wyciek pamięci?W języku Java, co dzieje się podczas oceniania argumentów wywołania konstruktora, generuje wyjątek?

Proszę zauważyć, że nie pytam "czy konstruktor może rzucić wyjątek", ale "co się stanie, jeśli konstruktor zgłasza wyjątek w określonej sytuacji."

obiekt O nie finalizable aż konstruktor powołuje konstruktora dla obiektu w O, a wywołanie jest zakończone powodzeniem (czyli nie powoduje wyjątku).

class A { 
    int n; 
    A(int n) { 
     this.n = n; 
    } 
} 

class B extends A { 
    B(int n) { 
     super(1/n); 
    } 
} 
+2

Myślę, że "finalizable" oznacza wywołanie 'finalize()', gdy obiekt jest GCed, * nie *, czy obiekt otrzyma GCed. –

+3

Możliwy duplikat [Czy konstruktorzy mogą zgłaszać wyjątki w Javie?] (Http://stackoverflow.com/questions/1371369/can-constructors-throw-exceptions-in-java) – mawalker

+0

@DavidEhrmann Dokładnie. To, czy obiekt jest finalizowany, jest w dużej mierze nieistotne, ponieważ prawie nie ma scenariuszy, w których należy używać finalizatorów. – biziclop

Odpowiedz

4

Sekcja jesteś powołując rozróżnia osiągalności i finalizability:

Każdy obiekt można scharakteryzować przez dwóch atrybutów: może być osiągalny, finalizator osiągalny lub nieosiągalny, a to może również być nieskończony, sfinalizowany lub sfinalizowany.

Obiekt może być osiągalny lub nieosiągalny, a także może być finalizowany lub niezawierający niezależnie.

W przypadku, o którym wspomniałeś, konstruktor Object nigdy nie był uruchamiany, więc obiekt nie jest finalizowany, ale OTOH konstruktor wyrzucił wyjątek, więc przypisanie wyniku new do zmiennej nigdy się nie dzieje, więc jest nieosiągalny .

Nie ma wycieku pamięci.

+1

Możesz uruchomić [ten mały test] (http://pastebin.com/A5tMhAxw) za pomocą opcji "-verbose: gc", aby to sprawdzić. W rzeczywistości przypadek "niepowodzenia" działa znacznie szybciej i znacznie szybciej kasuje pamięć, co brzmi zaskakująco, dopóki nie spojrzysz, w jaki sposób realizowana jest finalizacja, i jak utrzymuje ona GC i spowalnia wszystko. – biziclop

Powiązane problemy