一. 回顾类的运行期常量
类的静态常量: public static final
当 MyTest 类的方法调用 MyChild 中运行期常量时就需要初始化 MyChild 类及其所有父类
当 MyTest 类的方法调用 MyChild 中编译期常量时不需要初始化 MyChild 类及其所有父类, 由于编译期常量被放在 MyTest 类的常量池中了
类的静态变量: public static
当 MyTest 类的方法中调用子类名. 父类静态变量, 会初始化父类, 不会初始化子类
当 MyTest 类的方法中调用子类名. 子类静态变量, 会初始化父类和子类
二. 分析接口
由于接口中的属性默认为 public static final, 则默认为静态常量. 则和类的静态常量的运行期和编译期一模一样.
三. 例题分析
结论: 静态变量初始化顺序从上到下依次进行
(1) 案例一
- public class MyTest5 {
- public static void main(String[] args) {
- Singleton singleton = Singleton.getInstance();
- System.out.println("counter1:"+Singleton.counter1);
- System.out.println("counter2:"+Singleton.counter2);
- }
- }
- class Singleton {
- public static int counter1;
- public static int counter2 = 0;
- private static Singleton singleton = new Singleton();
- private Singleton(){
- counter1++;
- counter2++;
- }
- public static Singleton getInstance(){
- return singleton;
- }
- }
- /*
- * 输出:
- * counter1: 1
- * counter2: 1
- * */
分析初始化过程:
调用 getInstance 方法返回 singleton, 此时调用初始化过程
准备阶段: 代码从上往下先进行静态变量赋默认值, counter1 = 0,counter2 = 0,singleton = null
初始化阶段: counter2 = 0,singletton 调用私有构造函数得 counter1 = 1,counter2 = 1
结果为 counter1 = 1,counter2 = 1
(2) 案例二
案例二只是将案例一中的 public static int counter2 = 0; 位置改变了.
- public class MyTest5 {
- public static void main(String[] args) {
- Singleton singleton = Singleton.getInstance();
- System.out.println("counter1:"+Singleton.counter1);
- System.out.println("counter2:"+Singleton.counter2);
- }
- }
- class Singleton {
- public static int counter1;
- private static Singleton singleton = new Singleton();
- private Singleton(){
- counter1++;
- counter2++;
- }
- public static int counter2 = 0;
- public static Singleton getInstance(){
- return singleton;
- }
- }
- /*
- * 输出:
- * counter1: 1
- * counter2: 0
- * */
分析初始化过程:
调用 getInstance 方法返回 singleton, 此时调用初始化过程
准备阶段: 代码从上往下先进行静态变量赋默认值, counter1 = 0,singleton = null,counter2 = 0
初始化阶段: singletton 调用私有构造函数得 counter1 = 1,counter2 = 1, 再 counter2 = 0
结果为 counter1 = 1,counter2 = 0
来源: http://www.bubuko.com/infodetail-3415448.html