根据JLS(Java Language Specification)中的定义,class在初始化过程中,需要同时初始化class中定义的静态初始化程序和在该类中声明的静态字段(类变量)的初始化程序。
而对于static变量来说,如果static变量被定义为final并且它值是编译时常量值,那么该static变量将会被优先初始化。
那么使用了final static变量,是不是就没有初始化问题了呢?
我们来看下面一个例子:
public class StaticFiledOrder{private final int result;private static final StaticFiledOrder instance = new StaticFiledOrder();private static final int intValue=100;public StaticFiledOrder(){result= intValue - 10;}public static void main(String[] args){System.out.println(instance.result);}}
输出结果是什么呢?
答案是90。根据我们提到的规则,intValue是final并且被编译时常量赋值,所以是最先被初始化的,instance调用了StaticFiledOrder类的构造函数,最终导致result的值是90。
接下来,我们换个写法,将intValue改为随机变量:
public class StaticFiledOrder{private final int result;private static final StaticFiledOrder instance = new StaticFiledOrder();private static final int intValue=(int)Math.random()* 1000;public StaticFiledOrder(){result= intValue - 10;}public static void main(String[] args){System.out.println(instance.result);}}
运行结果是什么呢?
答案是-10。为什么呢?
因为instance在调用StaticFiledOrder构造函数进行初始化的过程中,intValue还没有被初始化,所以它有一个默认的值0,从而导致result的最终值是-10。
怎么修改呢?
将顺序调换一下就行了:
public class StaticFiledOrder{private final int result;private static final int intValue=(int)Math.random()* 1000;private static final StaticFiledOrder instance = new StaticFiledOrder();public StaticFiledOrder(){result= intValue - 10;}public static void main(String[] args){System.out.println(instance.result);}}