2012-06-11 5 views
8

L'ho avvicinata al caso dell'eliminazione di qualsiasi oggetto usuale, ovvero, semplicemente rendendo il riferimento nullo e lasciando che Garbage Collector faccia il suo lavoro.In java, come è possibile distruggere un'istanza di una classe da un metodo all'interno della classe

Tuttavia per equiparare a null all'interno di una classe, l'unico riferimento all'oggetto è "questo". Così è valido il codice valido per la seguente classe:

class A{ 
    public A(){ 
    //Init 
    } 

    public void method destruct(){ 
    if(someCondition){ 
     this=null; //Is this statement valid? Why/Why not? 
    } 
    } 
} 
+1

Se "questo" è * veramente * l'unico riferimento all'oggetto, il gioco è fatto: è idoneo per GC non appena lasci il metodo e alla fine verrà rimosso. –

+9

Il numero di upvotes è un po 'distruttivo. :] –

+0

... che non sarà @ Joachim, in quanto ci sarebbe stato un chiamante. – lotsoffreetime

risposta

11
this=null; //Is this statement valid? Why/Why not? 

non è valida perché Java this non è un lvalue; non è qualcosa che puoi assegnare a Questo è un errore di compilazione, proprio come 42 = i; è un errore di compilazione.

(Il JLS dice il seguente su assegnazioni: "Il risultato del primo operando di un operatore di assegnazione deve essere una variabile, o in fase di compilazione si verifica un errore."-JLS 15.26.1 Il testo JLS passa poi alla lista le cose diverse che si qualificano come variabili, e this non è una di queste.)

Inoltre, come dice duffymo, è una cosa totalmente sbagliata da fare in Java. Lascia che il GC faccia il suo lavoro.

+0

+1 - Perfetta spiegazione usando lvalue. Assolutamente la risposta giusta. – duffymo

18

Non si "distruggono" oggetti in Java. Questo è sbagliato. Non farlo

Gli oggetti vengono creati nell'heap in Java. Vivono finché c'è un riferimento che li indica. Il netturbino ripulisce il casino.

Dovresti certamente fare ciò che puoi per assicurarti di non accumulare e trattenere i riferimenti inutilmente (ad esempio ascoltatori in Swing).

Ma la tua proposta non è la cosa giusta. Cessare e desistere.

0

Per il garbage collector java per raccogliere la classe, non si dovrebbe fare riferimento alle ALTRE classi.

La dichiarazione this=null; è illegale perché la parte sinistra di un compito deve essere una variabile.

1

Il tuo obiettivo è profondamente fuorviante.

O qualcuno all'esterno dell'istanza contiene un riferimento non debole. Quindi non verrà raccolto indipendentemente da ciò che fai all'interno. O nessuno lo fa, quindi alla fine verrà raccolto, indipendentemente da quello che fai dentro. In entrambi i casi, this=null non avrebbe fatto alcuna differenza, anche se fosse un codice java legale. Non farlo Se sei preoccupato della durata dell'oggetto e dell'esaurimento della memoria, guarda fuori dall'oggetto che vuoi eliminare.

0

Non esiste un modo per specificare esplicitamente delete in Java. Java lo fa per evitare riferimenti sospesi. Se si imposta un oggetto con lo delete, altri oggetti ad esso relativi possono potenzialmente tentare di accedere ai dati e ottenere un riferimento a dati non validi.

Non si dovrebbe provare a oggetti delete in ogni caso, è sufficiente spostare tutti i riferimenti all'oggetto su null.

3

NOTA: ciò che suggerisci è altamente improbabile che sia utile.

Quello che puoi fare è usare la delega.

class A { 
    private AImpl impl = new AImpl(); 

    public void close() { 
     if (impl != null) 
     impl.close(); 
     impl = null; 
    } 
} 

Come tutti i riferimenti sono indiretti, è possibile garantire c'è un solo riferimento all'oggetto reale e cancellarlo.


I proxy in alcuni contenitori OSGi lo fanno quando un componente viene scaricato. Poiché il contenitore ha un controllo limitato sul ciclo di vita dei riferimenti, renderebbe difficile scaricare una libreria (l'implementazione).

0

No. Un oggetto di istanza può essere eliminato dal GC quando nessun riferimento punta ad esso, che il suo, da tutti i thread in esecuzione non può navigare fino all'oggetto. Quando si è nell'oggetto che esegue un metodo, questo metodo viene richiamato dall'esterno, quindi esiste un riferimento all'oggetto. L'oggetto stesso non può essere distrutto, poiché un riferimento ad esso rimane ancora all'esterno.

Considerare un altro approccio per la gestione della memoria.

1

L'impostazione this = null è come provare a dire che un oggetto non fa riferimento a se stesso. Si riferisce sempre implicitamente a se stesso. Devi trovare quali altri oggetti potrebbero fare riferimento a questo e cancellare i loro riferimenti. Di solito, ciò accade automaticamente perché la maggior parte degli oggetti viene mantenuta tramite variabili locali che sono nello stack. Quando dico "mantenuto" intendo che sono referenziati attraverso una catena di riferimenti che alla fine porta a una variabile in pila. Quando lasci il metodo, il riferimento viene cancellato. Ma se si dispone di una variabile statica che fa riferimento a questo oggetto potrebbe essere un caso in cui è necessario impostarlo in modo esplicito.

0

Nei metodi this è un riferimento all'oggetto su cui viene richiamato il metodo corrente, pertanto non dovrebbe essere possibile modificarlo. Pensa a questo come riferimento finale.

0

Il ciclo di vita degli oggetti è regolato dalla JVM, per questo motivo un oggetto non può decidere quando non è più necessario. Quello che potresti fare è mettere un po 'di impegno sui riferimenti a questo oggetto. È possibile utilizzare il tipo di riferimenti per indicare "l'importanza" dell'oggetto.

I principali tipi di riferimenti in Java si possono trovare qui:

Maggiori informazioni qui: http://docs.oracle.com/javase/1.3/docs/api/java/lang/ref/package-summary.html

Discussione sui riferimenti qui: What is the difference between a soft reference and a weak reference in Java? e Understanding Java's Reference classes: SoftReference, WeakReference, and PhantomReference

0

È possibile chiamare:

System.gc() or RuntimeUtil.gc() from the jlibs 

ma se lo fai scherzi con il runtime JVM. Se si imposta refernce su null, l'oggetto esiste ancora, il suo solo riferimento non si riferirà a questo oggetto e al successivo richiamo di GC esso distruggerà l'oggetto (a meno che altri riferimenti si riferiscano ad esso).

0

Nessun codice precedente non è valido. Il riferimento this di una classe dura solo finché viene eseguita la JVM. L'impostazione this == null ti darà infatti un errore del compilatore perché sebbene this sia definito come riferimento, in realtà è un valore e non puoi assegnare nulla a a un valore.

Inoltre non è necessario poiché this è valido solo fino a quando l'esecuzione è in tale codice e GC non può rivendicare un oggetto che è ancora in esecuzione. Tuttavia, non appena l'esecuzione termina per l'oggetto, anche l'oggetto this andrà perso e l'oggetto diventerà automaticamente disponibile per GC (cioè se nessun altro riferimento all'oggetto esiste)

0

Questo è un errore di compilazione. Non puoi assegnare NULL a "questo". La parola chiave 'this' può essere usata sul lato destro di equals (con l'eccezione che la mano sinistra non è NULL. Motivo: nulla può essere assegnato a null).

Per la distruzione, in Java, hai un GC che può fare questo lavoro per te dietro le quinte.

Si prega di notare che per gli oggetti definiti dall'utente si può ancora fare qualcosa di simile -

object reference = null; 

Tuttavia 'questo' non può essere utilizzato sul lato sinistro del pari.

0

Il vero motivo per cui il thread di esecuzione è all'interno del metodo destruct() mi dice che c'è un chiamante che contiene un riferimento a questa istanza della classe A. Quindi, tuttavia, non puoi fare nulla del tipo "this = null "in Java - non avrebbe aiutato, anche se era permesso in Java. Non puoi distruggere oggetti in java.