public class Test {
public static int a = 1;
private int b = 1;
static{
System.out.println("静态代码块中 a:"+a);
a = 2;
}
{
System.out.println("代码块中 b:"+b);
b = 2;
}
public Test(int num) {
super();
System.out.println("构造函数中 b:"+b);
this.b = num;
System.out.println("构造函数显示初始化后 b:"+b);
}
public static void main(String[] args) {
ClassLoader classLoader = Test.class.getClassLoader();
while (classLoader != null) {
System.out.println(classLoader);
classLoader = classLoader.getParent();
}
System.out.println(classLoader);
new Test(3);
}
}
结果:
静态代码块中 a:1
sun.misc.Launcher$AppClassLoader@105d88a
sun.misc.Launcher$ExtClassLoader@cb6009
null
代码块中 b:1
构造函数中 b:2
构造函数显示初始化后 b:3
类初始化总过程:
加载: 查找并加载类的二进制数据(*.class)到内存,将其放在运行时数据区的方法区中(父加载机制),
然后在堆中创建一个Class对象,用于封装类在方法区的数据结构
Class对象封装了类在方法区的数据结构,并且向Java程序提供了访问方法区的数据结构的接口
根类加载器(Bootstrap):C++实现,输出为null
扩展类加载器(Ext):jre\lib\ext目录下加载
应用类加载器(app):CLASSPATH下加载
连接: 1、验证:确保被加载类的正确性
2、准备:为类的静态变量分配内存,并将其初始化为默认值 (a=0)
3、解析:把类中的符号引用转化为直接引用
初始化: 为类的静态变量赋予正确的初始值,两种方式(依次按顺序执行):
1、声明处初始化 (a=1)
2、静态代码块中初始化 静态代码块中 a:1
new object() (a=2)
构造函数执行
1、成员变量默认初始化 (b=0)
2、调用super()
3、成团变量初始化 (b=1)
4、代码块执行 代码块中 b:1
(b=2)
5.构造函数显示初始化 构造函数中 b:2
(b=3)
构造函数显示初始化后 b:3
至此对象新建成功,传递对象引用至引用变量。