深度思考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语言的设计不好的地方。