http://bookshadow.com/weblog/2016/02/28/java-variable-initialization-problem/
首先来看笔者遇到的一道面试题,阅读下面的代码并给出执行结果:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
读完这段代码,笔者的第一个念头是由于
counter1
没有赋初始值,所以会导致编译错(害羞),但面试官指出这段代码可以通过编译。
然后笔者又给出了答案
“1 1”
,因为笔者觉得 public static int counter2;
与 public static int counter2 = 0;
是等价的。
但实际上程序的实际运行结果是
“1 0”
,这是为什么呢?
Java中的变量根据作用域可划分为成员变量和局部变量两类。
而需要注意的是,Java对于成员变量的初始化,实际上是分解为两步执行的。
对于静态成员变量:
对于动态成员变量:
上面的
Singleton
类的初始化过程实际上可以转化为:- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
执行过程如下:
如果将
Singleton
的counter1
和counter2
更改为动态变量,结果又是什么呢?- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
Singleton
类的代码可以转化为:- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
此时,
Singleton
类初始化的顺序如下: