1. 一个class文件加载的流程
1.1 加载:查找并加载类的二进制数据 , 将class文件加载到内存
1.2 连接
– 准备:为类的静态变量分配内存,并将其初始化为默认值
– 解析:把类中的符号引用转换为直接引用
1.3 初始化:为类的静态变量赋予正确的初始值
2. class对象、静态变量、静态方法 ,保存在方法区,为所有线程共享
3. 一个类如果拥有父类,这个类初始化的时候需要先初始化其父类, 而父类的调用不会初始化子类
public class TestParent {
public static void main(String[] args) {
new C();
new D();
}
}
class P1 {
static {
System.out.println( " p static ");
}
}
class C extends P1 {
static {
System.out.println(" c static ");
}
}
class D extends P1 {
static {
System.out.println(" D static ");
}
}
输出 :
p static
c static
D static
先初始化C的父类P,然后再初始化C,初始化D的时候,由于其父类已经被初始化,所以不再初始化其父类,直接初始化D
4. 调用一个类中的静态变量时,会初始化该类, 调用静态常量时, 如果常量可以在编译时确定,不会初始化该类,如果需要在运行时确定,则需要初始化该类
public class TestStaticFinal {
public static void main(String[] args) {
int a = C.x;
int b = D.x;
int c = E.x;
}
}
class C {
//静态变量
static int x = 2;
static {
System.out.println(" C static ");
}
}
class D {
//静态常量, 编译时可确定常量的值
static final int x = 3 + 2;
static {
System.out.println(" D static ");
}
}
class E {
//静态常量, 运行时才能确定其值的大小
static final int x = new Random().nextInt(10);
static {
System.out.println(" E static ");
}
}
输出结果
C static
E static
结果显示: C类型静态变量会初始化, D编译时常量不会加载初始化, E运行时常量会初始化该类