2016-03-05 7 views
8

Si consideri il semplice esempio in Java di seguito. Cosa succede se creo un oggetto chiamando new B(0)? Innanzitutto, un oggetto di tipo B è stato creato in memoria. Quindi, l'espressione 1/n genererà un'eccezione. Ma l'oggetto creato non sarà mai finalizzato secondo le specifiche Java (§12.6.1) di seguito. Quindi abbiamo una perdita di memoria?In Java, cosa succede quando si valutano gli argomenti di una chiamata del costruttore si genera un'eccezione?

Si noti che non sto chiedendo "può un costruttore lanciare un'eccezione", ma "cosa succede se un costruttore lancia un'eccezione in una situazione particolare".

Un oggetto o non è finalizable finché il costruttore ha invocato il costruttore Oggetto oe che invocazione ha completato con successo (cioè senza un'eccezione).

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

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

Penso che "finalizzabile" si riferisce a 'finalize()' viene chiamato quando l'oggetto è GCed, * not * indipendentemente dall'oggetto GCed. –

+3

Possibile duplicato di [I costruttori possono lanciare eccezioni in Java?] (Http://stackoverflow.com/questions/1371369/can-constructors-throw-exceptions-in-java) – mawalker

+0

@DavidEhrmann Esatto. Se un oggetto è o meno finalizzabile è in gran parte irrilevante in quanto non ci sono quasi scenari in cui si dovrebbero usare i finalizzatori. – biziclop

risposta

4

La sezione che stai citando distingue tra raggiungibilità e finalizability:

Ogni oggetto può essere caratterizzata da due attributi: può essere raggiungibile, finalizzatore-raggiungibile, o non raggiungibile, ed è può anche essere non finalizzato, finalizzabile o finalizzato.

Quindi un oggetto può essere raggiungibile o irraggiungibile e finalizzabile o non finalizzabile, indipendentemente.

Nel caso menzionato, il costruttore Object non è mai stato eseguito, quindi l'oggetto non è definibile, ma OTOH il costruttore ha emesso un'eccezione in modo che l'assegnazione del risultato new a una variabile non avvenga mai, quindi è irraggiungibile .

Quindi non c'è perdita di memoria.

+1

È possibile eseguire [questo piccolo test] (http://pastebin.com/A5tMhAxw) con '-verbose: gc' per verificarlo. In effetti, il caso "fallito" viene eseguito molto più velocemente e cancella la memoria molto più velocemente, il che suona solo sorprendente fino a quando non viene esaminato il modo in cui la finalizzazione è implementata, e come mantiene il GC e rallenta tutto – biziclop

Problemi correlati