Ben çok yaşlıyım. Orada bulundum ve gördüm ve kafamı çok sık çarptım.
IBM erkeklerinin bize bu yeni Java dilinin ne kadar harika olduğunu anlattıkları Hursley Park'taki bir konferanstaydım, sadece birisi sordu ... neden bu nesneler için bir yıkıcı yok. C ++ 'da yıkıcı olarak bildiğimiz bir şeyi kastetmedi, ancak sonlandırıcı da yoktu (ya da sonlandırıcıları vardı ama temelde işe yaramadı). Bu çok geriye döndü ve Java'nın bu noktada biraz oyuncak dil olduğuna karar verdik.
Şimdi de finalizatörleri dilin teknik özelliklerine eklediler ve Java bazı uyarlamalar gördü.
Tabii ki, daha sonra herkese finalistleri nesnelerine koymadıkları söylendi çünkü GC'yi inanılmaz derecede yavaşlattı. (yalnızca yığını kilitlemekle kalmayıp, sonlandırılacak nesneleri geçici bir alana taşımak zorunda kaldığından, bu yöntemler GC'nin uygulamayı çalıştırmasını duraklattığı için çağrılamaz. Bunun yerine hemen sonraki çağrılırlar. GC döngüsü) (ve daha da kötüsü, uygulama kapatıldığında bazen sonlandırıcı hiçbir zaman hiç aranmaz. Dosya tanıtıcınızın hiç kapalı olmadığını hayal edin)
Sonra C # 'ye sahip olduk ve MSDN'deki tartışma forumunu hatırlıyorum. Birisi neden deterministik bir sonlandırma olmadığını sordu ve MS çocukları bize bu tür şeylere nasıl ihtiyaç duymadığımızı söylediler, sonra bize uygulamalar tasarlama biçimimizi değiştirmemiz gerektiğini söylediler, sonra bize GC'nin ne kadar şaşırtıcı olduğunu ve tüm eski uygulamalarımızın nasıl olduklarını anlattılar Çöp ve tüm dairesel referanslar nedeniyle hiç çalışmadı. Sonra baskıya girdiler ve bu İddialı paterni kullanabileceğimiz şartnameye eklediklerini söylediler. Bu noktada C # uygulamalarında bizim için manuel bellek yönetimine döndüğümüzü sanıyordum.
Tabii ki, MS'li çocuklar daha sonra bize anlattıklarının hepsinin ... iyi olduğunu keşfettiler, IDispose'ı standart bir arayüzden biraz daha fazla yaptılar ve daha sonra use deyimini eklediler. W00t! Deterministik sonlandırmanın sonuçta dilden eksik bir şey olduğunu fark ettiler. Tabii ki, yine de her yere koymayı hatırlamalısın, bu yüzden hala biraz el kitabı, ama daha iyi.
Öyleyse neden baştan beri her bir kapsam bloğuna otomatik olarak stil anlambilgisi yerleştirmiş olurlarsa bunu yaptılar? Muhtemelen verimlilik, ama sadece farkına varmadıklarını düşünmekten hoşlanıyorum. Sonunda olduğu gibi hala NET'te akıllı işaretçilere ihtiyacınız olduğunu anladılar (google SafeHandle) GC'nin gerçekten tüm sorunları çözeceğini düşünüyorlardı. Bir nesnenin sadece bellekten daha fazlası olduğunu ve GC'nin öncelikle bellek yönetimini idare etmek için tasarlandığını unutmuşlardır. GC'nin bunu halledeceği fikrine kapıldılar ve oraya başka şeyler koyduğunuzu unuttular, bir nesne sadece bir süre silmediğiniz önemli olmayan bir bellek bloğu değildir.
Ancak, orijinal Java’daki bir sonlandırma yönteminin olmamasının da bundan biraz daha fazlası olduğunu düşünüyorum - yarattığınız nesnelerin tamamen bellekle ilgisi olduğunu ve başka bir şey silmek istiyorsanız (bir DB tutacağı veya bir soket veya başka bir şey gibi) ) o zaman manuel olarak yapmanız bekleniyordu .
Java'nın, insanların pek çok manuel tahsisatlı C kodu yazmaya alışkın olduğu gömülü ortamlar için tasarlandığını, bu nedenle otomatik olarak özgür olmamanın çok fazla bir sorun olmadığını - daha önce hiç yapmadıklarını, neden Java’ya ihtiyacınız olduğunu hatırlayın. Sorun, iş parçacığı ya da yığın / öbek ile ilgili bir şey değildi, muhtemelen bellek ayırmayı (ve dolayısıyla ayırmayı) biraz daha kolaylaştırmak için oradaydı. Sonuç olarak, try / finally deyimi, bellek dışı kaynakları işlemek için muhtemelen daha iyi bir yerdir.
Yani IMHO, .NET'in basitçe Java'nın en büyük kusurunu kopyalaması en büyük zayıflığı. .NET daha iyi bir C ++ olmalıydı, daha iyi bir Java.