小女巫 发表于 2015-1-18 11:47:50

JAVA教程之了解finalize()-析构函数替换者

再说说缺点:首先java功能强大的背后是其复杂性,就拿web来说,当今流行的框架有很多,什么struts,spring,jQuery等等,而这无疑增加了java的复杂性。函数
了解finalize()-析构函数替换者







在很多方面,Java相似于C++。Java的语法十分相似于C++,Java有类、办法和数据成员;Java的类有机关函数;Java有非常处置。







可是,假如你利用过C++会发明Java也丢失落一些多是你熟习的特征。这些特征之一就是析构函数。代替利用析构函数,Java撑持finalize()办法。







在本文中,我们将形貌finalize()与C++析构函数的区分。别的,我们将创立一个复杂的Applet来演示finalize()是怎样事情的。







终极的界线







与Java分歧,C++撑持部分对象(基于栈)和全局对象(基于堆)。由于这一两重撑持,C++也供应了主动机关和析构,这招致了对机关函数和析构函数的挪用,(关于堆对象)就是内存的分派和开释。







在Java中,一切对象都驻留在堆内存,因而部分对象就不存在。了局,Java的计划者以为不必要析构函数(象C++中所完成的)。







取而代之,Java界说了一个特别的办法叫做finalize(),它供应了C++析构函数的一些功效。可是,finalize()其实不完整与C++的析构函数一样,并能够假定它会招致一系列的成绩。finalize()办法感化的一个关头元素是Java的渣滓接纳器。







渣滓接纳器







在C/C++、Pascal和其他几种多种用处的编程言语中,开辟者有义务在内存办理上发扬主动的感化。比方,假如你为一个对象或数据布局分派了内存,那末当你不再利用它时必需开释失落该内存。







在Java中,当你创立一个对象时,Java假造机(JVM)为该对象分派内存、挪用机关函数并入手下手跟踪你利用的对象。当你中断利用一个对象(就是说,当没有对该对象无效的援用时),JVM经由过程渣滓接纳器将该对象标志为开释形态。







当渣滓接纳器将要开释一个对象的内存时,它挪用该对象的finalize()办法(假如该对象界说了此办法)。渣滓接纳器以自力的低优先级的体例运转,只要当其他线程挂起守候该内存开释的情形呈现时,它才入手下手运转开释对象的内存。(现实上,你能够挪用System.gc()办法强迫渣滓接纳器来开释这些对象的内存。)







在以上的形貌中,有一些主要的事变必要注重。起首,只要当渣滓接纳器开释该对象的内存时,才会实行finalize()。假如在Applet或使用程序加入之前渣滓接纳器没有开释内存,渣滓接纳器将不会挪用finalize()。







其次,除非渣滓接纳器以为你的Applet或使用程序必要分外的内存,不然它不会试图开释不再利用的对象的内存。换句话说,这是完整大概的:一个Applet给大批的对象分派内存,没有形成严峻的内存需求,因而渣滓接纳器没有开释这些对象的内存就加入了。







明显,假如你为某个对象界说了finalize()办法,JVM大概不会挪用它,由于渣滓接纳器未曾开释过那些对象的内存。挪用System.gc()也不会起感化,由于它仅仅是给JVM一个倡议而不是命令。







finalize()有甚么长处呢?







假如finalize()不是析构函数,JVM纷歧定会挪用它,你大概会困惑它是不是在任何情形下都有优点。现实上,在Java1.0中它并没有太多的长处。







依据Java文档,finalize()是一个用于开释非Java资本的办法。可是,JVM有很年夜的大概不挪用对象的finalize()办法,因而很难证实利用该办法开释资本是无效的。







Java1.1经由过程供应一个System.runFinalizersOnExit()办法部分地办理了这个成绩。(不要将这个办法与Java1.0中的System.runFinalizations()办法相搅浑。)不象System.gc()办法那样,System.runFinalizersOnExit()办法其实不当即试图启动渣滓接纳器。而是当使用程序或Applet加入时,它挪用每一个对象的finalize()办法。







正如你大概推测的那样,经由过程挪用System.runFinalizersOnExit()办法强迫渣滓接纳器扫除一切自力对象的内存,当扫除代码实行时大概会引发分明的提早。如今创建一个示例Applet来演示Java渣滓接纳器和finalize()办法是怎样互相感化的。







接纳渣滓







经由过程利用JavaAppletWizard创立一个新的Applet入手下手。当提醒如许做时,输出final_things作为Applet名,并选择不要天生源文件正文。







接上去,在JavaAppletWizard举行第三步,不要选择多线程选项。在第五步之前,依据必要修正Applet的形貌。







当你单击Finish后,AppletWizard将天生一个新的事情空间,并为该项目创立缺省的Java文件。从列表A当选择得当的代码输出(我们已凸起显现了你必要输出的代码)。







当你完成代码的输出后,设置Internet扫瞄器将System.out的输入信息写到Javalog.txt文件中。(在IE选项对话框的初级页面当选择升引JavaLogging。)



编译并运转该Applet。然后,守候Applet运转(你将在形态栏中看到Applet已启动的信息),加入扫瞄器,并翻开Javalog.txt文件。你将会发明相似于以下行的信息:







1000thingsconstructed



0thingsfinalized







正如你可以看到的那样,创建了1,000个对象仍旧没有迫使渣滓接纳器入手下手接纳空间,即便在Applet加入时也没有对象被利用。







如今,删除在stop()办法第一行中的正文符以升引System.gc()办法。再次编译并运转该Applet,守候Applet完成运转,并加入扫瞄器。当你再次翻开Javalog.txt文件,你将看到以下行:







1000thingsconstructed



963thingsfinalized







此次,渣滓接纳器以为年夜多半对象未被利用,并将它们接纳。按按次,当渣滓接纳器入手下手开释这些对象的内存时,JVM挪用它们的finalize()办法。







承继finalize()?







特地,假如你在类中界说了finalize(),它将不会主动挪用基类中的办法。在我们会商了finalize()与C++的析构函数的分歧点后,对这个结论不会惊奇,由于为某个类定制的扫除代码另外一个类纷歧定会必要。







假如你决意要经由过程派生一个类的finalize()办法来挪用基类中的finalize()办法,你能够象其他承继办法一样处置。







protectedvoidfinalize()



{



super.finalize();



//otherfinalizationcode...



}







除同意你把持是不是实行扫除操纵外,这个手艺还使你能够把持以后类的finalize()办法什么时候实行。







结论







但是无益的是,Java的主动渣滓接纳器不会得到均衡。作为便当的价值,你不能不保持对体系资本开释的把持。不象C++中的析构函数,JavaApplet不会主动实行你的类中的finalize()办法。现实上,假如你正在利用Java1.0,即便你试图强迫它挪用finalize()办法,也不克不及确保将挪用它。







因而,你不该当依托finalize()来实行你的Applet和使用程序的资本扫除事情。取而代之,你应该明白的扫除那些资本或创立一个try...finally块(或相似的机制)来完成。







列表A:final_things.java







importjava.applet.*;



importjava.awt.*;







classthing



{



publicstaticintthingcount=0;



publicstaticintthingfinal=0;







publicthing()



{



++thingcount;



}











protectedvoidfinalize()



{



++thingfinal;



}



}







publicclassfinal_thingsextendsApplet



{







publicfinal_things()



{



}







publicStringgetAppletInfo()



{



return"Name:final_thing
"+



"Author:TimGooch
"+



"CreatedwithMicrosoft"+



"VisualJ++Version1.1";



}











publicvoidinit()



{



resize(320,240);







}







publicvoiddestroy()



{



}







publicvoidpaint(Graphicsg)



{



g.drawString("CreatedwithMicrosoft"+



"VisualJ++Version1.1",10,20);



}







publicvoidstart()



{



while(thing.thingfinal<1)



{



newthing();



}



}







publicvoidstop()



{



//System.gc();



System.out.println(thing.thingcount+



"thingsconstructed");



System.out.println(thing.thingfinal+



"thingsfinalized");



}







}







C#是盗用了Java的源代码,仿照开发的,原因是Java是开源的啊,盗了也白盗,还有一点,开发C#语言的团队是就是开发Java语言的团队,是微软重金挖过去的啊

分手快乐 发表于 2015-1-20 15:59:10

Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。

蒙在股里 发表于 2015-1-24 17:44:28

吧,现在很流行的Structs就是它的一种实现方式,不过Structs用起来实在是很繁,我们只要学习其精髓即可,我们完全可以设计自己的MVC结构。然后你再研究一下软件Refactoring (重构)和极限XP编程,相信你又会上一个台阶。 做完这些,你不如整理一下你的Java代码,把那些经典的程序和常见的应用整理出来,再精心打造一番,提高其重用性和可扩展性。你再找几个志同道合的朋友成立一个工作室吧

若相依 发表于 2015-2-15 19:36:02

那么我书也看了,程序也做了,别人问我的问题我都能解决了,是不是就成为高手了呢?当然没那么简单,这只是万里长征走完了第一步。不信?那你出去接一个项目,你知道怎么下手吗,你知道怎么设计吗,你知道怎么组织人员进行开发吗?你现在脑子里除了一些散乱的代码之外,可能再没有别的东西了吧!

莫相离 发表于 2015-3-4 12:48:14

是一种使用者不需花费很多时间学习的语言

飘飘悠悠 发表于 2015-3-6 20:18:02

你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。

因胸联盟 发表于 2015-3-11 00:03:19

当然你也可以参加一些开源项目,一方面可以提高自己,另一方面也是为中国软件事业做贡献嘛!开发者在互联网上用CVS合作开发,用QQ,MSN,E-mail讨论联系,天南海北的程序员分散在各地却同时开发同一个软件,是不是很有意思呢?

灵魂腐蚀 发表于 2015-3-12 11:39:03

所以现在应用最广泛又最好学的就是J2EE了。 J2EE又包括许多组件,如Jsp,Servlet,JavaBean,EJB,JDBC,JavaMail等。要学习起来可不是一两天的事。那么又该如何学习J2EE呢?当然Java语法得先看一看的,I/O包,Util包,Lang包你都熟悉了吗?然后再从JSP学起。

乐观 发表于 2015-3-17 10:08:20

是一种将安全性(Security)列为第一优先考虑的语言

小女巫 发表于 2015-3-19 04:47:59

关于设计模式的资料,还是向大家推荐banq的网站 http://www.jdon.com/,他把GOF的23种模式以通俗易懂的方式诠释出来,纯Java描述,真是经典中的经典。

再见西城 发表于 2015-3-24 23:28:21

是一种使用者不需花费很多时间学习的语言

柔情似水 发表于 2015-3-26 17:26:26

有时间再研究一下MVC结构(把Model-View-Control分离开的设计思想)

兰色精灵 发表于 2015-4-1 08:08:38

Java是一种计算机编程语言,拥有跨平台、面向对java

透明 发表于 2015-4-1 21:11:12

Java是一个纯的面向对象的程序设计语言,它继承了 C++语言面向对象技术的核心。Java舍弃了C ++语言中容易引起错误的指针(以引用取代)、运算符重载(operator overloading)

深爱那片海 发表于 2015-4-4 14:21:22

Java语言支持Internet应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括URL、URLConnection、Socket、ServerSocket等。Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。

谁可相欹 发表于 2015-4-14 00:40:50

一直感觉JAVA很大,很杂,找不到学习方向,前两天在网上找到了这篇文章,感觉不错,给没有方向的我指了一个方向,先不管对不对,做下来再说。

变相怪杰 发表于 2015-4-14 07:10:08

是一种由美国SUN计算机公司(Sun Microsystems, Inc.)所研究而成的语言

小妖女 发表于 2015-4-21 15:51:50

所以现在应用最广泛又最好学的就是J2EE了。 J2EE又包括许多组件,如Jsp,Servlet,JavaBean,EJB,JDBC,JavaMail等。要学习起来可不是一两天的事。那么又该如何学习J2EE呢?当然Java语法得先看一看的,I/O包,Util包,Lang包你都熟悉了吗?然后再从JSP学起。

冷月葬花魂 发表于 2015-5-2 19:56:38

不过,每次的执行编译后的字节码需要消耗一定的时间,这同时也在一定程度上降低了 Java 程序的运行效率。
页: [1]
查看完整版本: JAVA教程之了解finalize()-析构函数替换者