一、对象的初始化
public class Demo {
public static void main(String[] args) {
new Son();
}
}
class Father{
int count =1;
{
System.out.println("父类初始化代码块执行:count="+count);
}
public Father() {
show();
}
void show() {
System.out.println("Father show");
}
}
class Son extends Father{
int num =8;
{
System.out.println("初始化代码块执行:num="+num);
num=7;
}
public Son() {
super();
System.out.println("Son 构造函数执行:num="+num);
}
void show(){
System.out.println("Son show:num="+num);
}
}
//执行结果:
//父类初始化代码块执行:count=1
//Son show:num=0
//初始化代码块执行:num=8
//Son 构造函数执行:num=7
结果分析:
1.在实例化Son时会先判断Son类及其父类是否被加载进内存,如果有则执行实例化,如果没有则按照父类优先的顺序将Son和Father类加载进内存并且执行类的初始化(注意类的初始化和对象的初始化有所区别)
执行实例化的初始化过程:
2.按照父类优先的顺序为Son和Father类中的成员变量(除去静态变量)在堆内存中申请空间,并赋默认值(如:int为0);
3.从继承关系的最顶层按照1)成员变量显式赋值或执行初始化代码块(谁在前先执行谁)、2)构造代码块初始化 开始初始化(本例中顺序为:Object->Father->Son);
二、类的初始化
上面提到在类的实例化过程中,如果类没有被加载进内存,则会进行类的加载和类的初始化,类的初始话只是对静态成员和静态初始化代码块而言。
public class Demo {
public static void main(String[] args) {
System.out.println(Son.num);
}
}
class Father {
static int count = 1;
static {
System.out.println("父类静态初始化代码块执行:count=" + count);
}
}
class Son extends Father {
static int num = 8;
static {
System.out.println("子类静态初始化代码块执行:num=" + num);
num = 7;
}
}
// 执行结果:
//父类静态初始化代码块执行:count=1
//子类静态初始化代码块执行:num=8
//7
结果分析:
1.在调用Son的静态变量是发现Son没有在内存中,故而开始加载Son所关联的类(按父类优先的顺序加载)
2.按顺序为静态变量在内存中(方法区中的静态区)申请空间,并赋默认值0;
3.从继承关系的顶层开始执行初始化(静态变量显式赋值或执行静态初始化代码块(谁在前先执行谁));