Soy bastante viejo Estuve allí y lo vi y me golpeé la cabeza muchas veces.
Estaba en una conferencia en Hursley Park donde los chicos de IBM nos contaban lo maravilloso que era este nuevo lenguaje Java, solo alguien preguntó ... ¿por qué no hay un destructor para estos objetos? No quiso decir lo que conocemos como destructor en C ++, pero tampoco había finalizador (o tenía finalizadores pero básicamente no funcionaban). Esto es hace mucho tiempo, y decidimos que Java era un lenguaje de juguete en ese momento.
ahora agregaron Finalisers a las especificaciones del lenguaje y Java vio algo de adopción.
Por supuesto, más tarde a todos se les dijo que no pusieran finalizadores en sus objetos porque ralentizaba enormemente el GC. (ya que no solo tenía que bloquear el montón, sino también mover los objetos a finalizar a un área temporal, ya que estos métodos no podían invocarse ya que el GC ha detenido la ejecución de la aplicación. En su lugar, se llamarían inmediatamente antes del siguiente Ciclo GC) (y lo que es peor, a veces nunca se llama al finalizador cuando la aplicación se estaba cerrando. Imagina que nunca se cierra el identificador de archivo)
Luego tuvimos C #, y recuerdo el foro de discusión en MSDN donde nos dijeron lo maravilloso que era este nuevo lenguaje C #. Alguien preguntó por qué no había una finalización determinista y los chicos de MS nos dijeron que no necesitábamos tales cosas, luego nos dijeron que teníamos que cambiar nuestra forma de diseñar aplicaciones, luego nos dijeron cuán increíble era GC y cómo eran todas nuestras aplicaciones antiguas basura y nunca funcionó debido a todas las referencias circulares. Luego cedieron a la presión y nos dijeron que habían agregado este patrón IDispose a la especificación que podríamos usar. Pensé que era más o menos la vuelta a la gestión de memoria manual para nosotros en las aplicaciones de C # en ese momento.
Por supuesto, los chicos de MS más tarde descubrieron que todo lo que nos habían dicho era ... bueno, hicieron que IDispose fuera un poco más que una interfaz estándar, y luego agregaron la declaración de uso. W00t! Se dieron cuenta de que la finalización determinista era algo que faltaba en el lenguaje después de todo. Por supuesto, aún debe recordar colocarlo en todas partes, por lo que todavía es un poco manual, pero es mejor.
Entonces, ¿por qué lo hicieron cuando podrían haber tenido una semántica con estilo colocada automáticamente en cada bloque de alcance desde el principio? Probablemente eficiencia, pero me gusta pensar que simplemente no se dieron cuenta. Al igual que finalmente se dieron cuenta de que todavía necesita punteros inteligentes en .NET (google SafeHandle), pensaron que el GC realmente resolvería todos los problemas. Se olvidaron de que un objeto es más que solo memoria y que GC está diseñado principalmente para manejar la administración de memoria. quedaron atrapados en la idea de que el GC manejaría esto, y olvidaron que pusiste otras cosas allí, un objeto no es solo una gota de memoria que no importa si no lo eliminas por un tiempo.
Pero también creo que la falta de un método de finalización en el Java original tenía un poco más que eso: que los objetos que creaste tenían que ver con la memoria y si querías eliminar algo más (como un controlador de base de datos o un socket o lo que sea ) entonces se esperaba que lo hicieras manualmente .
Recuerde que Java fue diseñado para entornos embebidos donde las personas estaban acostumbradas a escribir código C con muchas asignaciones manuales, por lo que no tener un automático automático no era un gran problema; nunca lo hicieron antes, entonces, ¿por qué lo necesitarían en Java? El problema no tenía nada que ver con subprocesos, o pila / montón, probablemente solo estaba allí para facilitar un poco la asignación de memoria (y, por lo tanto, la desasignación). En general, la declaración try / finally es probablemente un mejor lugar para manejar recursos que no son de memoria.
En mi humilde opinión, la forma en que .NET simplemente copió el mayor defecto de Java es su mayor debilidad. .NET debería haber sido un mejor C ++, no un mejor Java.