Newsgroup: it.comp.java
Titolo: Distruttore

CIao a tutti.
per quel che so in Java non esiste il metodo distruttore. confermate?
Daniele

si non avrebbe senso perche tu non sai quando vengono distrutti 
realmente gli oggetti


vero, ma concorderai sull'utilità di un distruttore...


Ciao, (:-!
Il giorno 07/06/2004 alle ore 13:43 hai scritto:
 D> vero, ma concorderai sull'utilità di un distruttore...
L'utilita' di un distruttore e' molto discutibile.
Se ti serve per chiudere collegamenti o fare altre operazioni di "clean-up"
manualmente puoi benissimo inserire un metodo che chiami quando sei sicuro
non utilizzare piu' le funzioni di quella classe (con tutte le ovvie
conseguenze se per caso riutilizzi un'istanza che hai precedentemente
'chiuso'). Per esempio le classi che gestiscono gli stream hanno un metodo
close per chiudere manualmente lo stream, senza dover aspettare il gc.
Bye
-- 
Try not. Do, or do not. There is no try.
http://www.maccasoft.com

  D> vero, ma concorderai sull'utilitŕ di un distruttore...


 vero, ma concorderai sull'utilità di un distruttore...
Dopo molti (purtroppo molti!) anni di OO
non ho mai capito a cosa serva un distruttore...
Ho sempre fatto senza.
E non ho mai avuto problemi.
- Dario

Be dipende dal linguaggio...
in C++ è l'unico modo per tenere pulita la memoria quando ne allochi 
dinamicamente. sostenzialmente è di grande utilita in mille casi.
un altro esempio veloce che non si riferisce alla pulizia della memoria
è quella del salvataggio dello stato di un oggetto nel momento che 
questo viene deallocato...
Personalmente credo che ad avere un linguaggio che offre i distruttori 
non farei fatica a trovare un modo di usarli :-)
Saluti


ovviamente concordo.. :-)


 solo sul modo di fare fare le cose noiose a lui.. ;-pp
Scusate, ma il garbage collector non elimina proprio l'esigenza di avere
un distruttore, lasciando comunque le operazioni di clean-up più delicate
al programmatore, come nell'esempio già fatto per gli stream?
Ad esempio se si stanno trattando password, visto che non si sa quando il
gc passerà a dare una pulita alla memoria, conviene scrivere un metodo che
azzeri i char dell'array ogni volta che si finisce di trattare la password
(mai usare String, che è immutabile per le password!). Se non si è in una
sitauazione simile non serve preoccuparsi, visto che pensa a tutto il gc:
basta mettere a null le reference che non si vogliono più bindare ad una
certa istanza di una certa classe. O no?
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

il mio scopo era proprio il caso degli stream (e simili) in effetti...


 il mio scopo era proprio il caso degli stream (e simili) in effetti...
Allora non dovresti avere problemi, visto che il metodo close() esegue una
pulizia anche troppo accurata: ad esempio
FileInputStream fis = new FileInputStream("...");
ObjectInputStream ois = new ObjectInputStream(fis);
/*
...
*/
ois.close(); // Chiude tutti gli strea collegati, quindi anche fis!


no... il succo del discorso era fare eseguire il close dal distruttore..


 no... il succo del discorso era fare eseguire il close dal distruttore..
Allora, se assumiano che il distruttore è il gc:
Object ref = ...;
/*
...
*/
ref = null;
equivale ad una chiamata al distruttore (in realtà stai marcando l'oggetto
per il gc, che viene eseguito dalla VM come thread a bassa priorità), ma
all'atto pratico non c'è alcuna differenza visto che la gestione della
memoria in Java semplicemente non esiste.
Qualcuno mi corregga se sbaglio...


secondo me sbagli, perchè il .close() magari fa altre cose che il gc non 
sa che deve fare... mentre richiamando il metodo .close() all'interno di 
un distruttore della classe stessa tutto sarebbe ok.


 un distruttore della classe stessa tutto sarebbe ok.
Questa è una questione interessante. In close() chiude gli stream, ma se
si mette semplicemente la reference a null, che succede quando il gc
ripulisce la memoria? lo stream rimane in qualche modo "aperto", oppure ci
possono essere effetti collaterali imprevisti? giro la domanda a qualcuno
più esperto di me...


 vedo che hai afferrato perfettamente il punto... :-)
Sarei pronto a scommettere che l'effetto di close è lo stesso che si
ottiene se si imposta la reference dell'oggetto di tipo stream a null, ed
è passato il gc. Ma non scommettere tanto, dicamo al massimo una birra...
:)


non guardare il caso specifico...


 più esperto di me...
Il close di FileOutputStream è automaticamente chiamato
dal finalize di FileOutputStream e quindi quando il gc
ripulisce la memoria lo fa solamente dopo che è stato
chiamato close.
http://makeashorterlink.com/?S18C31F78
Semplice, no?
- Dario

 E non ho mai avuto problemi.
Poter usare un distruttore ha i suoi vantaggi (e pure notevoli), ma non è
certo qualcosa di cui non si possa fare a meno.
Ciao.

 chiamato close.
Ho vinto una birra :)


 per quel che so in Java non esiste il metodo distruttore. confermate?
No.
Dai un occhiata al metodo finalize()

 vero, ma concorderai sull'utilità di un distruttore...
In java, appurato che esiste un metodo (finalize()) che viene invocato 
dal gc prima di deallocare l'oggetto, è sconsigliato dare compiti 
critici a questo metodo. Non esiste distruzione esplicita dell'oggetto e 
in fase di scrittura di codice non hai alcuna certezza che il metodo 
venga mai chiamato, essendo legato alla completa dereferenziazione 
dell'oggetto che non è un evento certo nella vita del programma.
Anche per le operazioni di cleanup, non è buona pratica farci 
affidamento per il recupero di risorse (connessioni, handle di file, 
etc...) salvo che con l'intenzione di paracadute o ultima spiaggia 
quando tutto il resto del programma se n'è dimenticato.

 un distruttore della classe stessa tutto sarebbe ok.
FileInputStream/OutputStream invocano il metodo close() nel finalize(). 
Questo per assicurare che gli handle del sistema operativo siano chiusi 
quando l'oggetto viene deallocato definitivamente. Tuttavia NON è ok per 
nulla fare affidamento su questo, gli handle dei file sono risorse 
preziose e non va assolutamente bene "fidarsi" che tanto poi li chiude 
da se.

 
Si. Nota che ci sono i finalizer - che pero' fanno un lavoro abbastanza 
diverso. 

 delicate al programmatore, come nell'esempio già fatto per gli stream?
Dipende. Se usi l'approccio "resource acquisition is initialization"
(cfr. Stroustrup) ti serve un distruttore esplicito per controllare 
l'esatto momento di rilascio delle risorse.