没有析构函数,这个功能怎么实现? 我考,是我傻,还是java傻。我想实现有个类有多个方法,每个方法里都用到数据
没有析构函数,这个功能怎么实现? 我考,是我傻,还是java傻。
我想实现
有个类有多个方法,每个方法里都用到数据库,数据库连接可以从外部传入,如果外部没有传入,我就自己创建。
如果没有外部传入数据库,因为java 没有析构函数,那我就必须显式的加一个释放数据库连接的方式。
如果这个类提供给别人使用,别人一旦忘了调用destory,数据库连接池就完蛋了。
我考,是我傻,还是java傻。
main()
{
Test test1=new Test test()
test1.f1(a,b);
test1.f2(a,b)
test1.destory();
Test test2=new Test test()
test2.setconn(dbconn)
test2.f1(a,b);
test2.f2(a,b)
test2.destory();
}
class Test
{
connection conn=null;
boolean bCreateConn=false;
f1(a,b)
{
insert a,b;
}
f2(a,b,c)
{
insert a,b,c;
}
f3(a,b,c,d)
{
if(this.conn==null)
{
createconn()
}
insert a,b,c,d
}
setconn(dbconn)
{
this.conn=dbconn;
}
createconn()
{
bCreateConn=true;
this.conn=conn.connect(....)
}
destory
{
if(bCreateConn)
{
conn.close();
}
}
}
[解决办法]
兄弟 是你傻吧,哪个搞java不知道 要关闭 啊。
你还真呆
[解决办法]
java不是有finalize() 吗???和析构函数一样的啊
[解决办法]
不过垃圾回收器释放该类的时候才用到finalize() ,所以你最好显示的调用一下
[解决办法]
我是说显示调用垃圾回收器啊
[解决办法]
没有,你想啊,如果用C++,你new的话还要delete,java中你不需要delete,回收器给你做,方便的同时,那么势必要丢失一些东西,其实你可以这样,你用destory方法显式调用垃圾回收器,如果他调用了destory方法就皆大欢喜,如果忘了,那么等系统自动调用垃圾回收器的时候也释放了。
但是,系统还没调用垃圾回收器,但是用户结束掉程序了,这个时候就会出问题了,数据库连接池完蛋,不过这样的几率会少很多了,其实它不调用destory方法引发的问题是他程序设计的问题,错不在你,你能做的只是尽量帮他健壮点,智能化点。
[解决办法]
这种情况的确存在,提供给客户使用,如果客户忘记关闭,便会导致资源泄漏,这不是语言层面可以解决的问题。
[解决办法]
[解决办法]学习
[解决办法]路过!
[解决办法]f1(a,b)
{
insert a,b;
//在这释放连接.
}
[解决办法]UP
[解决办法]是finalize方法。
可以在finalize方法里面,调用destory方法,完成数据库连接的释放。
一般情况下,程序开发,都要有显示释放数据库连接的代码。
这样可以使资源得到及时的管理(或回收)。
而采用finalize方法释放资源的方式,会有一个显著地特点(或者说缺陷)。
就是,finalize方法的调用时间,是不可精确确定的。
这样,你程序中的资源何时被释放,也就变得的有些飘渺。
严重情况下,会导致系统瘫痪。
[解决办法]又要马儿跑,又要马儿不吃草
[解决办法]应该是你傻,因为所有数据库的链接都是需要释放的,就算你使用其它语言来实现,仍旧需要释放,区别是像C++这种语言把释放链接放入到析构函数中而已,而java则放入一个方法中。
如果你设计了一个数据库访问的类,或者说你实现了一个数据库访问层,然后这个层要其它业务来调用,那你就应该实现成业务调用不用来关心数据库访问的细节,比如数据库的打开与关闭,只用关系传入什么值得到什么值就可以了,如果不是这样,说明你的数据库访问设计得有问题。例如你完全可以在每次调用数据库模块开始打开数据库,调用结束关闭数据库。其实写java程序,你只要完全的去用面向对象的思想来解决问题,这些东西都可以被封装得很好,这完全是依靠你对语言的理解以及多架构的理解了。如果你觉得每次访问都要打开或者关闭数据库很消耗系统资源,没错、的确如此,这样就是很消耗数据库以及系统资源,因此你可以实现数据库连接池,关于这点你可以参考容器jndi的jdbc链接实现,也可以参考spring对jdbc的处理,也可以参考hibernate对数据库连接的封装出来。
[解决办法]
什么问题都出来了。
[解决办法]
还有,楼上各位所说的finalize方法,这个方法并不等于C++中的析构函数,C++中的析构函数的调用回收对象内存,但是java中的finalize方法正好相反,这个方法是回收内存时调用。也就是说,java中调用finalize方法根本不是回收内存,你调用它跟调用普通方法没有任何区别,也不能回收掉对象内存,它只是在对象内存回收的时候会被虚拟机调用一次而已。如果你想立即回收内存,你可以调用System.GC()方法来提醒虚拟机,系统内存将要不够,虚拟立即回收垃圾内存,但是垃圾回收器也不会因此回收掉内存,而是等待一个时机来尽快回收掉没有引用的游离对象而已。
如果你真的非常的必要手动来回收一个对象的内存,那么我只能很遗憾的告诉你,java语言机制没有这种能力,java不允许手动回收内存,甚至不允许任何形式的对内存的可控制操作。所以要实现手动回收必须绕过java语言机制来回收内存,也就是使用jni技术用其它有对内存进行可控制操作的语言来完成这种操作,例如C或者C++,可惜遗憾的是,这种做法很打程度上却违背了java的设计初衷,即不可跨平台以及不面向对象了,那么在这里使用java就成为了鸡肋,不如使用更切合的本地语言来实现功能要好得多了。
[解决办法]
是你傻,看看开源的数据库连接池的实现就知道了。里面会对一个连接超过一定时间没有使用,但又没有放回连接池而自动回收这个连接。引句PS名言:只有想不到,没有做不到。
[解决办法]
要用户自己释放
JDK设计Stream,Socket,Connection等类本身都是要用户自己调用Close的,你怕什么,他们不释放那是他们自己的事
[解决办法]
其实如果你用连接池就不会出现这种问题,你在每个方法的开头获得数据库,每个方法的结尾关闭数据库,这样就不会出现三个链接被占用,只是打开了三次链接,关闭了三次连接而已,不过这个地方如果使用了连接池技术,那么这个地方的打开数据库与关闭数据库其实不是真正意义上的打开与关闭,而是获得与归还,即你打开一个数据库的操做其实是你从连接池中获得一个连接,关闭数据库,只是把这个连接归还给连接池,而打开与关闭连接则是有连接池自己管理,连接池要自己判断,如果连接不够用则打开一个新连接,如果某个连接长期不被使用则关掉它,这个是连接池必须实现的一个基本功能,如果你的连接池是自己实现的,那么你必须实现连接池这种自我判断连接的功能。
如果你觉得每个方法都打开和关闭数据库这种方式不好,即使是形式上的你也觉得不爽,那么你可以参考hibernate的一种对连接的管理,即在一个高端去管理连接(例如web应用中的过滤器),即打开与关闭数据库在用户操作级别上去管理,或者应用启用级别上去管理。即你的方法ABC都不管理数据库的关闭与打开,而是想办法把用切面编程的方式,把数据库管理动态织入到业务调用层上(业务调用本身感觉不到以被织入数据库管理),这种方式编程工作量很大,难度也颇高,对于这点spring框架实现得很完美,它在用面向切面的方式对数据库连接以及事务的管理上做得非常好,你可以研究一下。
[解决办法]
[解决办法][解决办法][解决办法]数据库连接池还需要别人调用display?
那还叫连接池吗?
[解决办法]简单的问题,用完切断连接就好了
[解决办法]学习 NND
[解决办法]你就不会把数据连接方threadlocal里面啊,最后committe就是了。管他哪里创建的呢。
[解决办法]很明显的,lz是你傻...连关闭都不用?
难道有了析构你就不用控制了?
[解决办法]使用Runtime.addShutdownHook添加“关闭钩”
[解决办法]大家都知道打开一个什么连接时,不需要的时候都会调用close()方法去关闭连接的,打开流是这样,连接数据库也是这样
[解决办法]路过帮顶,up
[解决办法]绑定··
[解决办法]try......catch
觉得这个好,记录日志还方便。
[解决办法][解决办法][解决办法]首先这个问题用连接池不是一个好的方法,一,不是所有的地方都支持连接池。二,如果不是数据库连接,而是文件或其它的非内存资源。
我说说我的看法,在C++中资源的分配,释放都是自己管理的,而Java对资源是自动管理的,但仅限于内存资源,其它资源还是要我们自己来管理的,实际上Java也没有能力管理非内存资源。在C++我们需要自己判断什么时候该释放资源,有人会说,我们只需要放到析构里面释放就行了,但析构函数什么时候调用呢?是对象释放的时候,但是对象什么时候释放呢?这还是要我们自己判断的。所以说不管是Java还是C++这种情况都是要我们自己处理的,我们只能自己去判断什么时候会不再需要数据连接然后关闭,如何去判断当然要结何问题自己去分析了。还是有一种情况就是在程序退出的时候实现资源的释放,这在Java中一直就是可以实现这个功能的,以前用System.runFinalizersOnExit(true),现在有addShutdownHook(Thread hook)它可以在JVM运行实例退出的时候运行你注册的关闭钩子,至于finalizer()在Java中不是必须的东西,我们极少用到,除非一些特殊的情况,这在Java编程思想中有说明。
[解决办法]其实这个问题刚开始学Java的时候也是想不明白,我想很多初学者都会有这个经历,但是遗憾的是一般的Java教程上都没有对这个问题的说明,尤其是学过C++的最容易陷入进去。我沉的不是楼主傻也不是Java傻,是你看的书傻。
[解决办法]如果我在调用Arrays.binarySearch()之前没有调用Arrays.sort(),是否也能算灾难呢?
如果我在c++中new了而不delete又算什么?
程序员要对自己写的代码负责的,不能拉了XX就期望别人给你擦PP.
记得中在MFC中,有些对象new了之后还要自己去调用它的init方法之后才能正常使用的,那如果我忘了调用这个init方法,是否也是一种灾难?
[解决办法]try{
//所有操作数据库的代码写在此处
insert(Object o)
remove(int id)
.....
}
catch(Exception e){
}
finally{
if(con!=null)con.close();
con=null;
}
这样就不会关闭不了连接了
[解决办法]有析构你还不是要在里面写下close(); 这跟自己定义个方法关闭有什么区别?只要你心里清楚,析构无处不在
[解决办法]Java有必要加析构函数吗?
[解决办法]你应该去适应java,而不是去改变java. 因为这就是规范。
[解决办法]楼主你赢了,Java傻,你是天才。
Java配不上你,别用了,别污染了你天才的脑子。
[解决办法][解决办法][解决办法]这不是问题,数据库连接你应该是传递进去,然后再返回之前关闭
也就是在f2里面就关闭连接...
[解决办法][解决办法][解决办法] 你傻,鉴定完毕
[解决办法]数据库连接切记一条:谁调用谁关闭你方法调用就方法关闭
------解决方案--------------------
看来是Java语言,设计Java语言、类库、接口及API的大师们和全世界Java程序员们傻,他们居然没有发现这个问题。看来是楼主聪明,佩服,五体投地!!!
[解决办法]楼上的和楼上的楼上的你们都傻了,JAVA应该做成不需要连接就能获取到数据(意念传输)。
否则JAVA给一些人用就是JAVA傻了。
[解决办法]有个类有多个方法,每个方法里都用到数据库,数据库连接可以从外部传入,如果外部没有传入,我就自己创建。
-------------------------------------------------------------
这种在设计上就存在问题,不是做底层或者框架级的开发,把 Connection 对象传来传去会引发很多的问题,
将会导致连接你不知道在什么时候需要关闭。
[解决办法]连接你自己用完直接关闭就可以了,所创建的对象是不需要你显示回收内存的,如果你和方法调用者用的是同一个事务,那就当然要他自己去处理它的链接啊。你自己创建的你自己关闭,别人传入你这个方法的你不要管就是,另外可以从框架设计角度提供统一的事务管理
[解决办法][解决办法]没办法的事,只能在文档里提醒使用者注意了
finallize是靠不住的,因为不定什么时候调用呢
垃圾回收 or 析构函数,鱼与熊掌不能兼得
谁要是能解决这个问题,那就厉害了
[解决办法]路过
[解决办法]就算C++有析构函数,如果用户不delete怎么办?光靠程序不解决一切问题。
[解决办法]这个东西必须手动关闭
要是说c析构如何,但是你要是忘记delete,析构还不是一样没用。。。。。
[解决办法][解决办法][解决办法]最后发表下自己的,个人认为这个可能是java的技术缺陷,众所周知java有很多缺陷,可能是java开发人员在整合的时候自己的疏忽,也不能说谁傻,只能说给用户带来了不变,java不像微软开发的东西适合各个类型的人使用(即使是初学者),java有很多地方只有相关技术人员才能用,而且不了解java的很可能在使用时出项错误(如java区分大小写,但是COLOR.red你说是对还是错哪?当然是对的,但是为什么它不区分大小写哪,因为这是软件缺陷,如果你问我软件缺陷是什么,自己找,不过我要说这个给用户带来不便的问题就是软件缺陷)。所以总是有些人问关于软件缺陷方面的问题,你问为什么,我就告诉你问sun公司,他就是这么规定的,我也不知道。
[解决办法]楼主 实际的项目开发中一般不会这么做的。
一般都是专门的数据库管理的工具实现的。
或者是实现连接池或数据源来实现的。
[解决办法][解决办法]看到lz这句话
“有个类有多个方法,每个方法里都用到数据库,数据库连接可以从外部传入,如果外部没有传入,我就自己创建。 ”
就感觉lz有些走偏了。
lz的这个类,应该只关注于方法里面的逻辑,
而不应该负责创建。
finalize的答案只能让lz离正确的设计越走越远
lz三思
good luck
[解决办法]LZ,用ref包的虚引用,然后写到finalize析构函数里就能够达到你的要求
------解决方案--------------------
给你什么工具,你就拿什么工具去实现功能,考虑怎样实现才是lz的本分
[解决办法]兄弟,java的析构函数默认不执行,如果需要在垃圾回收的时候执行析构函数,那么你要在System中设置一下.那样就不要手工调用了.
但是析构函数里面有大量业务的话,会影响回收效率的.
再说,数据库连接,不用连接池么?频繁开关好像很消耗性能的.
[解决办法]aop 实现对某个方法的拦截,既可以在拦截前做一些事情,也可以拦截后做一些事情,你就创建一个切面,执行后拦截,在调用过你的方法后就执行关闭数据库的链接!!
[解决办法][解决办法]兄弟,只要是写这个的人,都知道去调用。凡是写java的人,如果连关闭都不知道的。他没资格从事这行业
[解决办法]哎,
[解决办法]你每天出去上班时关门吗?
[解决办法]在每一个调用数据库的方法最后加个finally块,在里面close()。统一样式的,写一个方法也可以,没什么麻烦的吧..........
[解决办法]是lz懒
[解决办法]连接池是不用关闭的,连接池自动会释放连接。不然要连接池干嘛啊
[解决办法]连接池不用关闭?不关闭连接,怎么把连接交还给连接池管理?
就算连接池智能到了不用你显式关闭,那么游标呢?交给“游标池”这种未来事物管理?
-------------
to楼主:析构方法,只有在栈上声明的实例会得到自动调用。如果用new分配,那一样要调用delete,否则别说外部资源,连内存都释放不了——还不如Java(当然这只是百步与五十步的区别)。如果你提出使用某些自动delete的框架来,那么Java也有自动管理连接的框架,当然流、游标一类的还是要自行管理——除非你做了面向这些切面的开发。
[解决办法]楼主真强悍 java不需要析构函数(尽管有finalize方法,但是最好不要用) 因为有垃圾回收机制 至于连接数据库的时候 使用完毕以后要手动关闭连接
[解决办法]楼主快结贴给分。
jvm还需要什么插件么?jni开发就是jvm的插件开发。