- 作者: gigix 2004年03月14日, 星期日 17:47
你可以使用这个链接引用该篇日志 http://publishblog.blogdriver.com/blog/tb.b?diaryID=82692
你在这里要用的是assert而不是exception.
因为没有释放连接是一个程序错误,在你的成品系统运行中是不应该出现的。我看不出在正式运行中抛出一个谁也解决不了的exception有什么意义,只能说在混淆视听。
如果你对测试覆盖率没有足够的信心,在成品系统中finalize中也应当有释放连接的代码(在那条assert之后),不过就像gigix说得那样,不到垃圾收集的时候连接池很可能就已经暴了
你没有看懂我的代码,我不需要finalize来关闭connection.而是要让虚拟机知道,如果运行到finalize还没有关闭connection那么就是一种异常,必须停止程序的运行。因此你可以
finalize()
{
if(this.isClose()==false)
throw new Exception();
}
或者更为严厉
finalize()
{
if(this.isClose()==false)
system.exit();
}
这个方法并不保证程序的正常运行,他只保证会检查出泄漏的资源。一个没有及时关闭的资源,一定会导致程序的中断。如果你要求更加好的资源管理,在C#,C++中都有相对的解决之道在java中恐怕除了小心的编写代码并无太好的办法。
Hibernate本身就做了这层管理,到垃圾回收的时候自然会关闭连接。但是就因为垃圾回收的非即时性,就已经足以把连接池灌爆了。要是依赖finalize的话,我们什么都不做都可以,压根就不会有这个话题。
请参看http://www.allaboutprogram.com/
这里的C++论坛,我,elminster,ajoo对resource leak有过充分的讨论。
解决这种问题最为简单的方法就是:
class MyConnection: extends Connection
{
finalize()
{
throw new UnCloseException();
}
}
我觉得这个问题和契约或者原本意义上的契约也没什么关系,而应当是一种协议,协议这个东西用契约很难表述出来或者说用契约表示就会看不到big picture。契约更多的是一个在调用点前后的横切视图,而不是一个动态的约束。
library搞得太复杂确实没有必要,可以弄一大堆assert来判断,但是这仅限于检查调用方是否合法,出现失败是要回头去改程序的,由调用方去确保其合法性。在最终的成品中,这些assert是不起作用的