Sono piuttosto vecchio. Ci sono stato, l'ho visto e ci ho sbattuto la testa molte volte.
Ero a una conferenza a Hursley Park in cui i ragazzi IBM ci dicevano quanto fosse meraviglioso questo nuovissimo linguaggio Java, solo qualcuno ha chiesto ... perché non c'è un distruttore per questi oggetti. Non intendeva la cosa che conosciamo come distruttore in C ++, ma non c'era neanche un finalizzatore (o aveva finalizzatori ma sostanzialmente non funzionavano). Questo è molto indietro, e abbiamo deciso che Java era un po 'un linguaggio giocattolo a quel punto.
ora hanno aggiunto Finalizzatori alle specifiche del linguaggio e Java ha visto l'adozione.
Naturalmente, in seguito a tutti è stato detto di non mettere i finalizzatori sui propri oggetti perché rallentava enormemente il GC. (poiché doveva non solo bloccare l'heap, ma spostare gli oggetti da finalizzare in un'area temporanea, poiché questi metodi non potevano essere chiamati poiché il GC ha messo in pausa l'app in esecuzione. Invece sarebbero stati chiamati immediatamente prima del successivo Ciclo GC) (e peggio, a volte il finalizzatore non veniva mai chiamato affatto quando l'app si chiudeva. Immagina di non avere mai il tuo file handle chiuso, mai)
Poi abbiamo avuto C # e ricordo il forum di discussione su MSDN in cui ci è stato detto quanto fosse meraviglioso questo nuovo linguaggio C #. Qualcuno ha chiesto perché non ci fosse una finalizzazione deterministica e i ragazzi della SM ci hanno detto come non avevamo bisogno di queste cose, poi ci hanno detto che dovevamo cambiare il nostro modo di progettare le app, poi ci hanno detto quanto fosse fantastico GC e come erano tutte le nostre vecchie app spazzatura e mai lavorato a causa di tutti i riferimenti circolari. Quindi hanno ceduto alla pressione e ci hanno detto che avevano aggiunto questo schema IDispose alle specifiche che potevamo usare. A quel punto ho pensato che fosse praticamente tornato alla gestione manuale della memoria nelle app C #.
Naturalmente, i ragazzi della SM in seguito hanno scoperto che tutto quello che ci avevano detto era ... beh, hanno fatto di IDispose un po 'più di una semplice interfaccia standard, e in seguito hanno aggiunto l'istruzione using. W00t! Si sono resi conto che la finalizzazione deterministica mancava dopo tutto alla lingua. Certo, devi ancora ricordarti di metterlo ovunque, quindi è ancora un po 'manuale, ma è meglio.
Quindi perché l'hanno fatto quando avrebbero potuto disporre automaticamente della semantica in stile utilizzo su ogni blocco dell'ambito dall'inizio? Probabilmente efficienza, ma mi piace pensare che non se ne siano resi conto. Proprio come alla fine si sono resi conto che hai ancora bisogno di puntatori intelligenti in .NET (google SafeHandle) hanno pensato che il GC avrebbe davvero risolto tutti i problemi. Hanno dimenticato che un oggetto è molto più di una semplice memoria e che GC è progettato principalmente per gestire la gestione della memoria. sono rimasti intrappolati nell'idea che il GC avrebbe gestito questo, e hanno dimenticato che hai messo altre cose lì dentro, un oggetto non è solo un blob di memoria che non importa se non lo elimini per un po '.
Ma penso anche che la mancanza di un metodo finalize nella Java originale avesse un po 'di più: che gli oggetti che hai creato riguardassero solo la memoria e se volessi eliminare qualcos'altro (come un handle DB o un socket o altro ), quindi ti aspettavi di farlo manualmente .
Ricorda che Java è stato progettato per ambienti embedded in cui le persone erano abituate a scrivere codice C con molte allocazioni manuali, quindi non avere il free automatico non era un problema: non l'avevano mai fatto prima, quindi perché dovresti averne bisogno in Java? Il problema non aveva nulla a che fare con i thread, o stack / heap, probabilmente era proprio lì per rendere un po 'più semplice l'allocazione della memoria (e quindi la de-allocazione). Nel complesso, l'istruzione try / finally è probabilmente un posto migliore per gestire risorse non di memoria.
Quindi IMHO, il modo in cui .NET ha semplicemente copiato il più grande difetto di Java è la sua più grande debolezza. .NET avrebbe dovuto essere un C ++ migliore, non un Java migliore.