萌萌妈妈 发表于 2015-1-18 11:32:07

JAVA网站制作之技能:提防代码的闭幕器毛病仓酷云

首先第一点:jsp,servlet,javabean这些最基本的,嘿嘿,就算你是高手的话,在大行的企业级应用的话还是需要框架的,一个好的框架确实能构解决许多问题。在利用闭幕器(finalizer)来创立对象时,其大概会给Java代码带来一个懦弱而易受打击的点。该毛病是这一为人人所熟知的利用闭幕器来回生对象手艺的一种变体。当一个有着finalize()办法的对象变得没法会见时,其就被安排在某个行列中,在晚些时分再加以处置。本篇文章注释了这一毛病是怎样起感化的,并给你展现了怎样回护你的代码免受其伤害,一切的这些代码例子都供应了下载。
闭幕器的设法是同意Java办法开释任何必要返还给操纵体系的当地资本,遗憾的是,任何的Java代码都能够在闭幕器中运转,其同意诸如清单1中的如许代码的实行:
清单1.一个可回生的类
publicclassZombie{
staticZombiezombie;

publicvoidfinalize(){
zombie=this;
}
}

当Zombie的闭幕器被挪用时,其用到了被闭幕的对象——经由过程this来援用——并把它保留在zombie这一静态变量中。如今该对象又是可会见的,其不克不及被渣滓搜集。
这一代码的一个加倍秘密的版本乃至同意一个只举行了部分机关的对象被回生,即便对象在初始化过程当中不克不及经由过程准确性反省,其仍可以被闭幕器创立出来,如清单2中的代码:
清单2.创立一个不法的类
publicclassZombie2{
staticZombie2zombie;
intvalue;

publicZombie2(intvalue){
if(value<0){
thrownewIllegalArgumentException("NegativeZombie2value");
}
this.value=value;
}
publicvoidfinalize(){
zombie=this;
}
}

在清单2中,对value参数举行反省的效果被finalize()办法的存在给抵消失落了。
打击是怎样失效的
固然,不成能会有人写出清单2那样的代码,但假如类被承继了的话,毛病就有大概呈现,如清单3中的类:
清单3.一个易受打击的类
classVulnerable{
Integervalue=0;

Vulnerable(intvalue){
if(value<=0){
thrownewIllegalArgumentException("Vulnerablevaluemustbepositive");
}
this.value=value;
}
@Override
publicStringtoString(){
return(value.toString());
}
}

清单3中的Vulnerable类的目标是避免value的值被设置成一个非负数,但这一目标被AttackVulnerable()办法给倾覆了,如清单4所示:
清单4.一个损坏了Vulnerable类的类

classAttackVulnerableextendsVulnerable{
staticVulnerablevulnerable;

publicAttackVulnerable(intvalue){
super(value);
}

publicvoidfinalize(){
vulnerable=this;
}

publicstaticvoidmain(String[]args){
try{
newAttackVulnerable(-1);
}catch(Exceptione){
System.out.println(e);
}
System.gc();
System.runFinalization();
if(vulnerable!=null){
System.out.println("Vulnerableobject"+vulnerable+"created!");
}
}
}

AttackVulnerable类的main()办法试图创立一个新的AttackVulnerable对象实例,由于value的值超越了局限,因而非常被抛出且在catch块中捕获到。System.gc()和System.runFinalization()的挪用促使VM运转一个渣滓接纳周期并运转一些闭幕器,这些挪用并不是是打击乐成的必须要素,不外它们可用来讲明打击的终极了局,了局是Vulnerable对象被创立了出来,有着一个有效的值。
测试用例的运转给出了以下的了局:
java.lang.IllegalArgumentException:Vulnerablevaluemustbepositive
Vulnerableobject0created!

为何Vulnerable的值是0而不是-1呢?能够注重到,在清单3的Vulnerable机关函数中,对value的赋值是在参数经由过程反省以后才会产生的,因而value具有的是初始值,在这一例子中是0。
这类打击乃至能够用来绕过显式的平安反省,比方,清单5中的Insecure类的计划设法是,假如其运转在一个SecurityManager的办理之下,且挪用者没有权限写进以后目次的话就抛出一个SecurityException。
清单5.Insecure类
importjava.io.FilePermission;

publicclassInsecure{
Integervalue=0;

publicInsecure(intvalue){
SecurityManagersm=System.getSecurityManager();
if(sm!=null){
FilePermissionfp=newFilePermission("index","write");
sm.checkPermission(fp);
}
this.value=value;
}
@Override
publicStringtoString(){
return(value.toString());
}
}

清单5中的Insecure类可遭到打击的体例和后面的一样,清单6在AttackInsecure类中给出了代码:
清单6.打击Insecure类
publicclassAttackInsecureextendsInsecure{
staticInsecureinsecure;

publicAttackInsecure(intvalue){
super(value);
}

publicvoidfinalize(){
insecure=this;
}

publicstaticvoidmain(String[]args){
try{
newAttackInsecure(-1);
}catch(Exceptione){
System.out.println(e);
}
System.gc();
System.runFinalization();
if(insecure!=null){
System.out.println("Insecureobject"+insecure+"created!");
}
}
}

运转在SecurityManager之下的清单6代码给出了以下的输入:
java-Djava.security.managerAttackInsecure
java.security.AccessControlException:Accessdenied(java.io.FilePermissionindexwrite)
Insecureobject0created!

怎样制止打击
直到Java言语标准(JavaLanguageSpecification,JLS)的第三版在JavaSE6中完成后,才有了这些制止打击的办法——利用initialized标记,克制子类化或是创立一个以final润色的闭幕器——不算是使人中意的办理计划。
利用initialized标记
一种制止打击的办法是利用initialized标记,一旦对象被准确创立该标记就设为true。类中的每一个办法先检察initialized标记是不是已设置,假如没有的话就抛出非常。这类编码体例写起来很烦人,不测的疏忽很简单就产生,而且不克不及制止打击者子类化办法。
避免子类化
你能够把所创立的类声明为final的,这意味着没有人可以创立该类的子类,从而制止了打击的得以举行。但是,这一技能打消了类的天真性,使得不克不及够经由过程扩大类来特别化它或是增加分外的功效。

创立一个final闭幕器
你能够为正在创立的类创立一个闭幕器并把它声明成final的,这意味着该类的任何子类都不克不及再声明闭幕器。这一办法的弱点是闭幕器的存在乎味着对象坚持存活的工夫善于其底本应当存活的工夫。
一种更新的、更好的做法
为了在不引进分外的代码或是限定的前提下更简单地制止这类打击,Java的计划者修正了JLS(拜见参考材料),划定假如java.lang.Object在构建之前有非常从机关函数中抛出的话,类的finalize()办法将不会被实行。
但在java.lang.Object被机关之前怎样大概会有非常被抛出呢?别忘了,任何机关函数的第一行必需是对this()或是super()的挪用,假如机关函数没有包含如许的显式挪用的话,一个对super()的挪用就会被隐含地增加出去。因而在对象被创立之前,统一个类或是它的父类的另外一个对象必需是已机关好了的。因而在任何来自机关中的办法的代码实行之前,这一划定终极会把实行引向java.lang.Object本身的机关函数,然后是一切子类的机关函数。
要了解非常怎样可以在java.lang.Object被机关之前抛出的话,你必要懂得对象机关切实其实切按次,JLS明白地注释了这一按次。
在对象被创立时,JVM:
1.为对象分派空间。
2.把对象中的一切实例变量的值设置成它们的默许值,这包含了对象的父类中的实例变量。
3.对对象参数变量举行赋值。
4.处置任何显式的或是隐式的机关函数挪用(机关函数中的this()或是super()挪用)。
5.初始化类中的变量。
6.实行机关函数中的其他部分代码。
关头的一点是,机关函数的参数处置是在机关函数外部的任何代码处置之行进行的,这意味着假如你在处置参数时举行考证的话,你能够——以抛出非常的体例——制止类被闭幕。
这带来了清单3中的Vulnerable类的一个新版本,如清单7所示:
清单7.Invulnerable类
classInvulnerable{
intvalue=0;

Invulnerable(intvalue){
this(checkValues(value));
this.value=value;
}

privateInvulnerable(VoidcheckValues){}

staticVoidcheckValues(intvalue){
if(value<=0){
thrownewIllegalArgumentException("Invulnerablevaluemustbepositive");
}
returnnull;
}

@Override
publicStringtoString(){
return(Integer.toString(value));
}
}

在清单7中,Invulnerable的私有机关函数挪用了一个公有的机关函数,该函数挪用checkValues办法来创立它的参数。该办法在机关函数做机关超类的挪用之前被挪用,这一超类的挪用就是Object的机关函数。因而假如非常从checkValue中抛出的话,Invulnerable对象就不会举行闭幕操纵。
清单8中的代码试图打击Invulnerable:
清单8.试图损坏Invulnerable类的实验
classAttackInvulnerableextendsInvulnerable{
staticInvulnerablevulnerable;

publicAttackInvulnerable(intvalue){
super(value);
}

publicvoidfinalize(){
vulnerable=this;
}

publicstaticvoidmain(String[]args){
try{
newAttackInvulnerable(-1);
}catch(Exceptione){
System.out.println(e);
}
System.gc();
System.runFinalization();
if(vulnerable!=null){
System.out.println("Invulnerableobject"+vulnerable+"
created!");
}else{
System.out.println("Attackfailed");
}
}
}

//增添的部份内容

//}else{
//System.out.println("Attackfailed");

假如是利用依据较旧的JLS版本编写的Java5的话,Invulnerable对象就会被创立出来:
java.lang.IllegalArgumentException:Invulnerablevaluemustbepositive
Invulnerableobject0created!

JavaSE6(从Oracle的JVM和IBMJVM的SR9的通用版公布入手下手)遵守了最新的标准,因而对象没有被创立:
java.lang.IllegalArgumentException:Invulnerablevaluemustbepositive
Attackfailed

结论
闭幕器是Java言语中一个使人遗憾的功效,只管渣滓搜集器能够主动地接纳任何不再被Java对象利用的内存,但并没有存在如许的机制往返收诸如当地内存、文件形貌符或是套接口一类的当地化资本。Java供应的与这些当地化资本做接口的尺度库一般会有一个close()办法来同意得当的清算——但它们还必要利用闭幕器来确保在对象没有被准确封闭时不会有资本泄露的情形产生。
就其他对象来讲,一样平常情形下最好制止利用闭幕器,由于其实不存在如许的包管,即闭幕器会在某个时分被实行,乃至究竟会不会被实行也不克不及包管。闭幕器的存在乎味着除非闭幕器已被运转,不然一个不克不及被会见的对象不克不及被渣滓搜集,,且这一对象乃至有大概会让更多的对象坚持在存活的形态中。这就招致了举动对象数量的增添,从而招致了Java历程的堆利用的增添。
闭幕器回生了一个预定要被渣滓搜集的对象,这一才能明显是闭幕操纵机制运作体例的一个意想不到的成果。如今JVM的较新完成同意你回护代码免遭这一成果所带来的平安隐患的威逼。
下载
形貌      称号      巨细    下载办法这一编程技能的代码例子j-fv.zip.zip4KBHTTP

关于下载办法的申明
参考材料
进修材料1.JavaLanguageSpecification:有关Java言语的手艺参考。
2.SecureCodingGuidelinesfortheJavaProgrammingLanguage:浏览这些原则来取得更多关于优秀的编程习气的倡议。
3.EffectiveJava,2ded.(JoshuaBloch,PrenticeHall,2008):本书包含了与闭幕器和其他的一些主要方面相干的成绩的一个会商。
4.Languagedesignersnotebook:懂得BrianGoetz的developerWorks系列文章,这一系列议论的是影响到Java言语将来的言语计划成绩。
5.Javatheoryandpractice:扫瞄BrianGoetz的这一临时开设的developerWorks系列,该系列是关于Java编程观点、技能和最好做法的。
6.developerWorksJavatechnologyzone:可找到数百篇关于Java编程的各个方面的文章。
猎取产物和手艺
1.以最合适你的体例来评价IBM的产物:下载产物试用版、在线试用产物、利用云情况中的产物,或是在SOASandbox中消费几个小时来进修怎样无效地完成面向服务的架构(ServiceOrientedArchitecture)。
会商
1.Javasecurity:列入developerWorks天主Java平安论坛。
2.到场developerWorks社区:在扫瞄开辟者驱动的博客、论坛、会商组和wiki时与其他developerWorks用户创建接洽。
关于作者

<br>NeilMasson多年来一向都在处置Java言语方面的开辟和撑持事情,今朝他的事情重点是改善Java刊行版本的质量和平安。


你说是sun公司对她研究的透还是微软?针对自己工具开发的.net网页编程性能上肯定会站上风的。

变相怪杰 发表于 2015-1-21 09:36:44

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

金色的骷髅 发表于 2015-1-28 08:21:08

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

乐观 发表于 2015-2-4 22:21:54

不过,每次的执行编译后的字节码需要消耗一定的时间,这同时也在一定程度上降低了 Java 程序的运行效率。

冷月葬花魂 发表于 2015-2-6 00:41:12

让你能够真正掌握接口或抽象类的应用,从而在原来的Java语言基础上跃进一步,更重要的是,设计模式反复向你强调一个宗旨:要让你的程序尽可能的可重用。

蒙在股里 发表于 2015-2-10 01:21:22

我大二,Java也只学了一年,觉得还是看thinking in java好,有能力的话看英文原版(中文版翻的不怎么好),还能提高英文文档阅读能力。

柔情似水 发表于 2015-2-17 20:38:04

Java 编程语言的风格十分接近C、C++语言。

小妖女 发表于 2015-3-1 10:59:42

是一种突破用户端机器环境和CPU

分手快乐 发表于 2015-3-10 14:55:43

你一定会高兴地说,哈哈,原来成为Java高手就这么简单啊!记得Tomjava也曾碰到过一个项目经理,号称Java很简单,只要三个月就可以学会。

飘飘悠悠 发表于 2015-3-11 08:22:09

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

山那边是海 发表于 2015-3-13 01:23:52

接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。

活着的死人 发表于 2015-3-20 09:05:45

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

老尸 发表于 2015-3-26 15:48:42

是一种为 Internet发展的计算机语言

兰色精灵 发表于 2015-3-26 19:53:37

Pet Store.(宠物店)是SUN公司为了演示其J2EE编程规范而推出的开放源码的程序,应该很具有权威性,想学J2EE和EJB的朋友不要 错过了。

不帅 发表于 2015-4-1 23:09:54

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

因胸联盟 发表于 2015-4-7 14:01:25

Pet Store.(宠物店)是SUN公司为了演示其J2EE编程规范而推出的开放源码的程序,应该很具有权威性,想学J2EE和EJB的朋友不要 错过了。

admin 发表于 2015-4-11 13:52:56

Jive的资料在很多网站上都有,大家可以找来研究一下。相信你读完代码后,会有脱胎换骨的感觉。遗憾的是Jive从2.5以后就不再无条件的开放源代码,同时有licence限制。不过幸好还有中国一流的Java程序员关注它,外国人不开源了,中国人就不能开源吗?这里向大家推荐一个汉化的Jive版本—J道。Jive(J道版)是由中国Java界大名 鼎鼎的banq在Jive 2.1版本基础上改编而成, 全中文,增加了一些实用功能,如贴图,用户头像和用户资料查询等,而且有一个开发团队在不断升级。你可以访问banq的网站

谁可相欹 发表于 2015-4-26 09:09:21

自从Sun推出Java以来,就力图使之无所不包,所以Java发展到现在,按应用来分主要分为三大块:J2SE,J2ME和J2EE,这也就是Sun ONE(Open Net Environment)体系。J2SE就是Java2的标准版,主要用于桌面应用软件的编程;J2ME主要应用于嵌入是系统开发,如手机和PDA的编程;J2EE是Java2的企业版,主要用于分布式的网络程序的开发,如电子商务网站和ERP系统。

深爱那片海 发表于 2015-4-26 17:12:13

你就该学一学Servlet了。Servlet就是服务器端小程序,他负责生成发送给客户端的HTML文件。JSP在执行时,也是先转换成Servlet再运行的。虽说JSP理论上可以完全取代Servlet,这也是SUN推出JSP的本意,可是Servlet用来控制流程跳转还是挺方便的,也令程序更清晰。接下来你应该学习一下Javabean了,可能你早就看不管JSP在HTML中嵌Java代码的混乱方式了,这种方式跟ASP又有什么区别呢?

仓酷云 发表于 2015-4-27 18:20:46

Java自面世后就非常流行,发展迅速,对C++语言形成了有力冲击。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于个人PC、数据中心、游戏控制台
页: [1] 2
查看完整版本: JAVA网站制作之技能:提防代码的闭幕器毛病仓酷云