0、本文要点:
- 类的生命周期
- 类的初始化顺序
- 总结
1、类的生命周期
首先谈到类的初始化过程,就不得不复习一下类的生命周期
类的生命周期如下:
(1)加载
(2)链接:1??验证;2??准备;3??解析
(3)初始化
(4)使用
(5)卸载
2、类的初始化顺序
(1)解释
这里我们所说的初始化顺序,其实是一个class文件里各个部分的执行顺序
(2)结论
前提:加载类方法(注意是加载)
第一步:
发生在链接-准备阶段的初始化:
1)为类常量(static final)赋正式值
2)为类变量赋默认值(注意是系统默认值,不是代码给定的初始值)
注意:类变量、静态代码块的执行顺序按代码顺序从上到下,代码块放在前面会先执行代码块,但此时代码块,可以对下面的类变量赋其他值,但是如果不能对类变量进行读取操作,否则会报 error: illegal forward reference(不合法的向前引用),这个道理也适用在对象变量和普通代码块中间。
第2步:
1)发生在初始化阶段的类变量赋初始值
执行静态代码块
第3步:
1)发生在使用阶段,如果new了对象
1??成员变量、普通代码块初始化
2??构造器
直接上代码:
public class Main { public static void main(String[] args) { System.out.println("Hello, World"); son.method();//静态方法调用 执行1、2 //new son(); //对象调用 执行1、2、3、4 } } class son{ //2、静态块1 static{ i = 666; System.out.println("静态代码块1"); } //1、静态变量 i\j,常量k赋默认值 //2、静态变量 i\j赋值初值值 static int i; static int j = 2; static final int k = 3; //2、静态块2 static{ System.out.println("静态代码块2"); j = 444; System.out.println("i = " + i + ",j = " + j + ",k = " + k); //i = 666,j = 444,k = 3 } //4、构造器 public son(){ a = 112; System.out.print("构造器" + ",j = " + j); System.out.print("构造器" + ",a = " + a); } //3、成员变量 int a = 111; //3、普通代码块 { System.out.print("代码块1"); b = 444; System.out.println("a = " + a ); //System.out.println("a = " + a + ",b" +b); //error: illegal forward reference 指b } int b = 333; public static void method(){ System.out.print("静态方法"); i = 333; System.out.println("i = " + i + ",j = " + j + ",k = " + k); //i = 333,j = 444,k = 3 } }
3、对于有继承关系的类初始化过程:
总结一句初始化来说就是:先父后子,先类(静态)后对象,对象构方法在最后。
另外附一道面试题,帮助了解类加载
public class Test { public static void main(String[] args) { A a = A.getInstance();
/*解题原则:类只加载一次,因此类变量只初始化一次,
A:
先执行类的实例化,此时需要类的初始化
然后类变量 value2 执行一次赋值
B:
先执行类的初始化,其中value2已经赋值,然后在执行对象定义,此时不会再初始化value1\value2
*/ System.out.println("A value1:" + a.value1);//1 System.out.println("A value2:" + a.value2);//0 B b = B.getInstance(); System.out.println("B value1:" + b.value1);//1 System.out.println("B value2:" + b.value2);//1 } } class A{ private static A a = new A(); public static int value1; public static int value2 = 0; private A(){ value1++; value2++; } public static A getInstance(){ return a; } } class B{ public static int value1; public static int value2 = 0; private static B b = new B(); private B(){ value1++; value2++; } public static B getInstance(){ return b; } }