Sono piuttosto vecchio. Sono stato lì e l'ho visto e mi ha sbattuto la testa molte volte.
Ero ad una conferenza a Hursley Park, dove i ragazzi dell'IBM ci dicevano quanto fosse meraviglioso questo nuovo linguaggio Java, solo qualcuno chiedeva ... perché non c'è un distruttore per questi oggetti. Non intendeva la cosa che conosciamo come un distruttore in C ++, ma c'era anche nessun finalizzatore (o aveva finalizzatori ma in pratica non funzionavano). Questo è molto tempo fa e abbiamo deciso che Java era un po 'un linguaggio giocattolo a quel punto.
ora hanno aggiunto Finalisers alle specifiche del linguaggio e Java ne ha visto l'adozione.
Naturalmente, più tardi è stato detto a tutti di non mettere i finalizzatori sui loro oggetti perché rallentava enormemente il GC. (poiché non doveva solo bloccare l'heap ma spostare gli oggetti finalizzati su un'area temporanea, poiché questi metodi non potevano essere chiamati in quanto il GC ha messo in pausa l'esecuzione dell'applicazione, ma sarebbero stati chiamati immediatamente prima del prossimo Ciclo GC) (e peggio, a volte il finalizzatore non verrebbe mai chiamato quando l'app si chiudeva. Immagina di non avere il tuo handle di handle chiuso, mai)
Poi abbiamo avuto C #, e ricordo il forum di discussione su MSDN dove ci è stato detto quanto fosse meraviglioso questo nuovo linguaggio in C #. Qualcuno ha chiesto perché non ci fosse una finalizzazione deterministica ei ragazzi della SM ci hanno detto che 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 GC fosse incredibile e come tutte le nostre vecchie app fossero spazzatura e mai lavorato a causa di tutti i riferimenti circolari. Poi cedettero alla pressione e ci dissero che avevano aggiunto questo schema IDispose alle specifiche che potevamo usare. A quel punto pensavo che fosse più tardi la gestione manuale della memoria per noi nelle app C #.
Ovviamente, i ragazzi della MS hanno scoperto in seguito che tutto quello che ci avevano detto era ... beh, hanno reso 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 era, in fondo, una cosa che mancava alla lingua. Certo, devi ancora ricordarti di metterlo ovunque, quindi è ancora un po 'manuale, ma è meglio.
Quindi perché lo hanno fatto quando avrebbero potuto usare semantica dello stile di utilizzo posizionata automaticamente su ogni blocco di scope dall'inizio? Probabilmente l'efficienza, ma mi piace pensare che semplicemente non se ne sono resi conto. Proprio come alla fine hanno capito 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 è più di una semplice memoria e che GC è stato progettato principalmente per gestire la gestione della memoria. sono stati presi dall'idea che il GC avrebbe gestito questo, e si sono dimenticati di mettere 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 nell'originale Java avesse un po 'di più in esso - che gli oggetti che hai creato riguardassero interamente la memoria, e se volessi cancellare qualcos'altro (come un handle di DB o un socket o qualsiasi altra cosa) ci si aspettava che lo facessero manualmente .
Ricordate che Java è stato progettato per ambienti embedded in cui le persone erano abituate a scrivere codice C con molte allocazioni manuali, quindi non avere automaticamente il free non era un grosso problema - non l'avevano mai fatto prima, quindi perché ne avreste bisogno Giava? Il problema non era niente a che fare con i thread, o stack / heap, probabilmente era solo lì per rendere l'allocazione della memoria (e quindi de-allocare) un po 'più facile. In generale, l'istruzione try / finally è probabilmente un posto migliore per gestire le 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.