2014-12-03 138 views
1

我在Java7中实现了一个类。它不会继承/实现任何东西。它使用Tess4J,所以我认为最后释放资源将会很好。所以我推翻这样的finalize()方法:为什么Netbeans警告我敲定?

@Override 
protected void finalize() throws Throwable 
{ 
    try 
    { 
     TessAPI1.TessBaseAPIDelete(handle); 
    } 
    catch(Throwable t) 
    { 
     throw t; 
    } 
    finally 
    { 
     super.finalize(); 
    } 
} 

Netbeans的8.0.2给我警告了这种方法:

finalize declared() 

的NetBeans网站上的描述是不是更有用的对我说:

warns about implementation of Object.finalize() 

我没有推翻像等号或任何其他方法(也许我应该?)。 你能告诉我为什么我会收到这个警告吗?

+1

相关阅读:http://weblog.ikvm.net/2003/11/09/FinalizeConsideredHarmful。as Java – 2014-12-03 11:43:31

+0

来自Effective Java的报道:“*终结器是不可预知的,通常是危险的,并且通常是不必要的*”。 – assylias 2014-12-03 11:48:07

+2

捕捉并立即重新抛出异常毫无意义。这种擒纵块可以被移除,因为它没有真正的效果。 – Natix 2014-12-03 11:54:25

回答

4

finalize方法都有它们可以在任意时间任意线程或所谓的甚至从来没有在所有的问题。和discussed in this question一样,它们可能会很早就被调用,即当实例方法仍在执行时,所以使用它们来释放资源是非常危险的。

因此,如果它们对于它们最初的目的不是很有用,那么在使用它们时总是发出警告是合理的。


如果要实施清理的资源,当客户端代码忘了打电话closedispose或任何你提供明确的资源管理(你应该如果有相关的本机资源)代码可以使用PhantomReference对实例和ReferenceQueue完成。

好处是,您可以控制何时轮询队列并执行清理,并且您甚至可以通过让PhantomReference超出范围(通常将收集并且未入队)来选择退出验尸清理)在客户端代码没有忘记调用close(它强烈建议执行AutoClosable允许使用try with resources”)的情况。因此,这也解决了性能小的问题,即必须收集具有非平凡finalize方法的对象两次,因为执行finalize方法意味着它们再次可达。

0

当jvm转到gc时调用finalize()。所以也许资源没有按照你的意愿发布。

最后改用试试。

+0

在对象生命期间多次调用处理,并且它有不同的类型。我是否可以用try-finally包围每个处理方法代码(这是否是一个好习惯)? – nuoritoveri 2014-12-03 12:09:02

2

一般来说,大多数Java程序员从来没有理由实现finalize(),因为他们自己的代码只使用已经管理的类(因此它们有自己的终结器)。 (请参阅问题下方的注释)。

有些开发人员可能不知道垃圾回收器是如何工作的,因此依靠finalize()来完成应该在其他地方完成的清理工作。这个错误尤其会导致在测试中不被注意的缺陷,但会导致生产失败。

出于这个原因,我想警告有关finalize()是合适的。

相关问题