据我所知,无法保证始终调用Object.finalize()
。但如果有一个重要的非GC资源,并且用户没有意外调用close()
,我该如何释放该资源?
PS。 .NET中的Object.Finalize()
是否有同样的问题?如果是这样,那么在这种情况下如何解决这个问题?
答案 0 :(得分:2)
您应该使用try-finally
或更好try-with-resources
try(Resource res = /*aquire resource*/){
//do stuff
}catch(Exception e //or watever){
//handle exceptions
}
以及如何在Java7之前完成它:
Resource res = null;
try{
res = //aquire resource
//do stuff
}catch(Exception e /*or whatever*/){
//handle exceptions
}finally{
if(null != res){
res.close();
}
}
在.Net中你应该使用
using (Resource resource = /*aquire resource*/)
{
//do stuff
}
简单的答案是YOU CANNOT
。这种行为是BUG
,您应该找到并修复它。
答案 1 :(得分:1)
.Net有同样的问题,Finalize
方法不可靠。因此,在.Net 2.0中解决了这个问题Safe Handles,它提供了一种释放非托管资源的可靠方法。
您所要做的就是从SafeHandle
或CriticalHandle
继承您的课程。这些都确实来自CritialFinializationObject
,它变成了可靠性的关键。
详细了解安全手柄here。
P.S:这只是部分答案,我是一个.Net的家伙,所以道歉没有java部分答案。答案 2 :(得分:0)
finalize
在.NET中有同样的问题(即如果对象永远不会被垃圾收集,那么将永远不会调用finalize)
在Java中,保证清理的最佳做法是:
final Resource resource = getResource();
try {
// Do stuff
...
} finally {
resource.dispose();
}
在.NET中,保证清理的最佳做法是:
using (Resource resource = GetResource())
{
// Do stuff
...
}