示例:
创建一个People类
public class People {
private String name;
private static People people = new People();
private static int n = 10;
private int age = setAge();
{
System.out.println("初始化块");
System.out.println("age = " + age);
}
static {
System.out.println("静态块");
System.out.println("n = " + n);
}
public static int setAge() {
return n++;
}
public People() {
System.out.println("默认构造函数");
System.out.println("age:" + age);
}
public People(String name, int age) {
this.name = name;
this.age = age;
System.out.println("有参构造函数");
System.out.println("age:" + age);
}
{
System.out.println("初始化块1");
System.out.println("age = " + age);
}
}
创建一个Student类,继承People类
public class Student extends People{
private static int num=20;
private String school;
{
System.out.println("student 初始化块");
school="河北小学";
System.out.println(school);
}
static {
System.out.println("student 静态块");
}
public Student() {
}
public Student(String name, int age) {
super(name, age);
System.out.println("student 构造函数");
}
}
创建一个Main类,实例化Student类
public class Main {
public static void main(String[] args) {
Student p = new Student();
Student p1=new Student("zhangsan",40);
}
}
执行结果:
初始化块
age = 0
初始化块1
age = 0
默认构造函数
age:0
静态块
n = 10
student 静态块
初始化块
age = 10
初始化块1
age = 10
默认构造函数
age:10
student 初始化块
河北小学
初始化块
age = 11
初始化块1
age = 11
有参构造函数
age:40
student 初始化块
河北小学
student 构造函数
分析结果:
1.Student p = new Student();
实例化一个Student对象。
2.先加载超类的静态部分,然后该子类的静态部分,再然后超类的非静态部分和构造器,最后子类的非静态部分和构造器。
3.进入超类People类,按顺序执行静态部分, private static People people = new People();
实例化一个People类,由于不是首次加载,所以该次实例化不再加载执行静态部分,而是按顺序执行非静态部分,private String name;
,private int age = setAge();
setAge方法是静态方法,已被加载到内存,故可以调用,执行return n++;
,由于n还未被初始化,故n被默认初始化为0,然后返回0,即age=0。
4.往下执行非静态块,打印出初始化块 , age = 0,继续往下执行非静态块,打印出初始化块1,age = 0,此时非静态部分执行完毕。
5.执行构造器方法People(),打印出默认构造函数,age:0。
6.此时 private static People people = new People();
实例化完成,接着往下执行People静态部分,private static int n = 10;
,n被赋值为10,。
7.然后往下执行静态块,打印出静态块,n = 10。
8.此时超类中的静态部分执行完毕,然后加载执行子类中的静态部分。
9.子类Student中的静态语句private static int num=20;
,然后往下执行静态块,打印出student 静态块,此时子类中的静态部分执行完毕。
10.接着执行超类中的非静态部分,private static int n = 10;
,n被赋值为10,private int age = setAge();
,age为10。
11.往下执行非静态块,打印出初始化块,age = 10,初始化块1,age = 10。
12.执行超类中的构造器方法,打印出默认构造函数,age:10。
13.然后,执行子类中的非静态部分,private String school;
,接着往下执行非静态块,打印出student 初始化块,河北小学。
14.最后,执行子类的构造器方法。到此为止,Student p = new Student();
实例化完毕。
15.Student p1=new Student("zhangsan",40);
带参进行实例化,由于不是第一次实例化,所以不再加载静态部分。
16.先是执行超类中的非静态部分 private String name;
,private int age = setAge();
,因为静态域n为11,故此时age为11。
17.往下执行非静态块,打印出初始化块,age = 11,初始化块1,age = 11。
18.执行People(String name, int age)构造器方法,传入参数,故age等于40,打印出有参构造函数,age:40。
19.执行子类中的非静态部分,打印出student 初始化块,河北小学。
20.最后执行子类的构造器方法,打印出student 构造函数。
总结:
第一次实例化时,先加载超类的静态部分,然后该子类的静态部分,再然后超类的非静态部分和构造器,最后子类的非静态部分和构造器。单个类中构造器初始化执行顺序,查看Java中调用构造器初始化执行顺序。