首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

深度思忖Java成员变量的初始化

2013-10-31 
深度思考Java成员变量的初始化写Java代码的时候很少去关注成员变量的声明和初始化顺序,今天借此机会抛出一

深度思考Java成员变量的初始化

         写Java代码的时候很少去关注成员变量的声明和初始化顺序,今天借此机会抛出一些问题:语言的设计者们为什么会这样设计?比如说很常见的一个问题:abstract(抽象)类不能用final进行修饰。这个问题比较好理解:因为一个类一旦被修饰成了final,那么意味着这个类是不能被继承的,而abstract(抽象)类又不能被实例化。如果一个抽象类可以是final类型的,那么这个类又不能被继承也不能被实例化,就没有存在的意义。从语言的角度来讲一个类既然是抽象类,那么它就是为了继承,所以给它标识为final是没有意义的。语言的设计者们当然不可能让这么大的一个bug产生。对于开发者而言抽象类不能修饰final可能就是一种约定俗成的规定,并没有特殊意义。我们完全可以往前想一点:为什么这么设计?

       下面我所展示的一些代码实例也同样会采用我上面的一些思考方法。有一些是一些”契约“,并没有特别的缘由,可能用别的方法也是合理的。下面的代码会讲到初始化的一些策略,从实际的执行结果中得出一些结论。


代码一
public class Test7 {        static{        a = 5;    }        private static final int a;            public static void main(String[] args){        System.out.println(a);    }}
      代码七和代码六的不同在于使用静态化的初始化方法,并不会违背final有且仅有一次赋值这样的一个约定。


总结

       上面七段代码大概阐述了一下变量的初始化顺序。大部分结果可以通过一些已有的结论推敲出来,也方便我们进行记忆。很多人可能会问:了解这些有用吗?如果只能看到我上面所写的那七段代码,可能意义并不大,在平常的编码过程中也不太可能会去那么写,即使写错了eclipse也会很明显的把错误指出来。而我得出的结论:从语言设计者的角度来思考Java语言为什么这么设计?如果这样去思考,然后再进行深度挖掘,一定可以得出一些不一样的理解,甚至可以找出java语言的设计不好的地方


11楼u01009034738分钟前
10楼lynnlovemin1小时前
顺便补充一句,代码四答案是会打印4,并且里面的System.out.println(a);也会输出,LZ没有测试过?而且理论上也不可能打印0撒,建议楼主看看jvm相关知识
Re: luohuacanyue1小时前
回复lynnloveminn我肯定是测试过的,你可以去测试一下,这里直接输出静态变量a,并不能触发动态块的执行,即使你把动态块放到变量后面也不会触发。这里为什么我也没想得很清楚,虽然后面我有自己的结论,但是仅仅是根据现象得出来的,目前我的解释只能是"lazy initial和按需加载“。说的直白点就是一种规范。代码三是会输出4的,因为代码三中new了一个对象,对静态变量进行了又一次赋值。
9楼u0117857662小时前
拜读了,思想挺好的...
Re: luohuacanyue1小时前
回复u011785766n思想很重要,知识积累一个重要的目标就是思考,有自己的想法。
8楼jiangfullll昨天 17:40
额,我的直观感受是,如果你会看javap的话,应该不是很难理解吧?
Re: luohuacanyue昨天 20:36
回复jiangfulllln这个我看过一些字节码,有一些问题是可以解决的,比如说int a =2和int a;{a=2;}这两种方式在字节码层面是一样的,但是仍然无法解释我在代码四中的问题。
7楼wu00103356昨天 15:48
看的很糊涂啊
Re: luohuacanyue昨天 17:24
回复wu00103356n确实会有点绕,建议静下心来自己演示一下!会比较有感觉。
6楼caodegao昨天 11:59
看到答案后,想想还是有点理解,如果作为编译是否正确的考试题,估计真不会看出问题的所在.基础啊基础,对你又爱又恨
5楼u012413257昨天 10:00
不是特别赞同在这一个点上纠结,但是作为java语言深度挖掘还是不错的!
Re: luohuacanyue昨天 11:28
回复u012413257n目前来讲对于Java语言层面很多东西都没有想透,基本上都限于使用方面,希望是一从至内而外的一种融会贯通。
4楼Etoak_james昨天 09:22
不错 顶了nnnQQ群:294881724 java高性能 和sql优化。
3楼yfkiss昨天 09:21
很棒的思考!赞下!
2楼suannai0314昨天 09:13
您的文章已被推荐到CSDN首页,感谢您的分享。
1楼lynnlovemin昨天 08:19
很简单,java的ClassLoader会首先将static加载,所以static变量会首先执行,所以在{a=4;System.out.println(a);}不会报错,因为在执行之前用static修饰的变量已经声明引用了,而没有被static修饰的会按照顺序依次加载,因此会报错,你试着将private int a;放到最前面,结果就不会报错。
Re: luohuacanyue昨天 08:41
回复lynnloveminn我知道放到前面是不会报错的,那样就得不出我想说的结论,这里我无法理解的是为什么这里可以赋值,而并不能使用?当然我在书中找到我在此文中标红的那个结论:”定义在声明之前的静态化块只能对声明变量进行赋值,并不能使用该变量“

热点排行