Questo è effettivamente indirizzata proprio dal linguaggio Java Specification, §12.6.1, Implementing Finalization:
Ottimizzazione trasformazioni di un programma possono essere progettati che riducono il numero di oggetti che sono raggiungibili a essere inferiori a quelle che avrebbe ingenuamente essere considerato raggiungibile. Ad esempio, un compilatore o un generatore di codice Java può scegliere di impostare una variabile o un parametro che non sarà più utilizzato per null
affinché l'archiviazione per tale oggetto sia potenzialmente recuperabile prima.
Un altro esempio di ciò si verifica se i valori nei campi di un oggetto sono memorizzati nei registri. Il programma può quindi accedere ai registri anziché all'oggetto e non accedere più all'oggetto. Ciò implicherebbe che l'oggetto è spazzatura. ...
Ma
... Si noti che questo tipo di ottimizzazione è consentito solo se i riferimenti sono in pila, non memorizzata nel mucchio.
Ad esempio, si consideri il modello di Finalizer Guardian:
class Foo {
private final Object finalizerGuardian = new Object() {
protected void finalize() throws Throwable {
/* finalize outer Foo object */
}
}
}
il finalizzatore forze guardiano super.finalize
di essere chiamato se una sottoclasse sovrascrive finalize
e non richiama esplicitamente super.finalize
.
Se queste ottimizzazioni sono consentite per i riferimenti archiviati nell'heap, un compilatore Java può rilevare che il campo finalizerGuardian
non viene mai letto, annullato, raccolto immediatamente l'oggetto e chiama il finalizzatore in anticipo. Ciò va contro l'intento: il programmatore probabilmente voleva chiamare il finalizzatore Foo
quando l'istanza Foo
non era raggiungibile. Questo tipo di trasformazione non è quindi legale: l'oggetto della classe interna dovrebbe essere raggiungibile fintanto che l'oggetto della classe esterna è raggiungibile.
Questo esempio può essere applicato 1: 1 per il tuo esempio, fino a quando l'oggetto viene riferimento il campo di istanza classObject
, non può ottenere garbage collection prima di quanto l'istanza Test
contenente il riferimento.
Si noti, tuttavia, che le ottimizzazioni aggressive menzionate nelle specifiche sono ancora consentite, quando vengono applicate al codice utilizzando l'istanza Test
. È possibile che si verifichi la raccolta precedente alle aspettative, purché sia, sia l'istanza Test
e l'oggetto di riferimento vengano raccolti insieme. In questo caso, si applica il seguente aspetto specificato in §12.6:
Il linguaggio di programmazione Java non impone alcun ordine sulle chiamate di metodo finalizzate. I finalizzatori possono essere chiamati in qualsiasi ordine, o anche contemporaneamente.
Quindi è perfettamente possibile che l'istanza Test
viene raccolto prima di quanto l'oggetto a cui fa riferimento, mentre classObject
finalizzatore di un oggetto “interiore” viene richiamato in precedenza. L'unica cosa che è garantita è che, quando viene eseguito il finalizzatore dell'oggetto interno, l'oggetto esterno non è raggiungibile (o ha una finalizzazione in sospeso o simultanea). Dal momento che nel tuo esempio, nessuno dei due ha un finalizzatore non banale, non importa comunque ...
Quando si dice "l'oggetto", si fa riferimento all'istanza della classe 'Test',' Object classObject' o 'Object myObject'? –
@LuiggiMendoza "l'oggetto" fa sempre riferimento all'oggetto originariamente indicato da myObject. – Dorothy