课程咨询 :186 8716 1620      qq:2066486918

昆明Java培训 > 达内新闻 > java培训:不要只替换一个类
  • java培训:不要只替换一个类

    发布:昆明Java培训      来源:达内新闻      时间:2016-09-30

  • 昆明达内Java培训的老师经常在系统中定义一个常量接口(或常量类),以囊括系统中所涉及的常量,从而简化代码,方便开发,在很多的开源项目中已经采用了类似的方法,比如在struts2中,org.apache.struts2.StrutsConstants就是一个常量类,它定义Struts框架中与配置有关的常量,而org.apache.struts2.StrutsConstants则是一个常量接口,其中定义了OGNL访问的关键字。

    关于常量接口(类)我们开看一个例子,首先定义一个常量类:

    public class Constant {

    //定义人类寿命极限

    public static final int MAX_AGE=150;

    }

    这是一个非常简单的常量类,定义了人类的最大年龄,我们引用这个常量,代码如下:

    public class Client{

    public static void main(String[] args) {

    System.out.println("人类的寿命极限是:"+Constant.MAX_AGE);

    }

    }

    运行结果easy,故省略。目前的代码是写在"智能型"IDE工具中完成的,下面暂时回溯到原始时代,也就是回归到用记事本编写代码的年代,然后看看会发生什么事情(为什么要如此,下面会给出答案)

    修改常量Constant类,人类的寿命极限增加了,最大活到180,代码如下:

    public class Constant {

    //定义人类寿命极限

    public static final int MAX_AGE=180;

    }

    然后重新编译,javac Constant,编译完成后执行:java Client,大家猜猜输出的年龄是多少?

    输出的结果是:"人类的寿命极限是150",竟然没有改成180,太奇怪了,这是为何?

    原因是:对于final修饰的基本类型和String类型,编译器会认为它是稳定态的(Immutable Status)所以在编译时就直接把值编译到字节码中了,避免了在运行期引用(Run-time Reference),以提高代码的执行效率。对于我们的例子来说,Client类在编译时字节码中就写上了"150",这个常量,而不是一个地址引用,因此无论你后续怎么修改常量类,只要不重新编译Client类,输出还是照旧。

    对于final修饰的类(即非基本类型),编译器会认为它不是稳定态的(Mutable Status),编译时建立的则是引用关系(该类型也叫作Soft Final)。如果Client类引入的常量是一个类或实例,及时不重新编译也会输出最新值。

    千万不可小看了这点知识,细坑也能绊倒大象,比如在一个web项目中,开发人员修改了一个final类型的值(基本类型)考虑到重新发布的风险较大,或者是审批流程过于繁琐,反正是为了偷懒,于是直接采用替换class类文件的方式发布,替换完毕后应用服务器自动重启,然后简单测试一下,一切Ok,可运行几天后发现业务数据对不上,有的类(引用关系的类)使用了旧值,有的类(继承关系的类)使用的是新值,而且毫无头绪,让人一筹莫展,其实问题的根源就在于此。

    还有个小问题没有说明,我们的例子为什么不在IDE工具(比如Eclipse)中运行呢?那是因为在IDE中设置了自动编译不能重现此问题,若修改了Constant类,IDE工具会自动编译所有的引用类,"智能"化屏蔽了该问题,但潜在的风险其实仍然存在,我记得Eclipse应该有个设置自动编译的入口,有兴趣大家可以自己尝试一下。

    昆明达内Java培训的老师提醒大家注意:发布应用系统时禁止使用类文件替换方式,整体WAR包发布才是万全之策。但我觉得应特殊情况特殊对待,并不可以偏概全,大家以为呢?

    推荐文章

上一篇:java中断言绝对不是鸡肋

下一篇:用偶判断,不用奇判断

最新开班日期  |  更多

Java--零基础全日制班

Java--零基础全日制班

开班日期:12/29

Java--零基础业余班

Java--零基础业余班

开班日期:12/29

Java--周末提升班

Java--周末提升班

开班日期:12/29

Java--零基础周末班

Java--零基础周末班

开班日期:12/29

  • 网址:http://km .java.tedu.cn      地址:昆明市官渡区春城路62号证券大厦附楼6楼
  • 课程培训电话:186 8716 1620      qq:2066486918    全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内国际公司(TARENA INTERNATIONAL,INC.) 版权所有 京ICP证08000853号-56