最近在校招笔试中遇到好几次求子类、父类构造器执行顺序问题,基本能做出来,但有些复杂的也挺耗时。查了些资料,再结合自己做的测试,总结一下贴在这里。
创建一个Person父类,分别定义有参构造器、无参构造器。
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
System.out.println("person有参构造器");
}
public Person() {
System.out.println("person无参数构造器");
}
再创建继承了Person类的Student类
public Student() {
super();
System.out.println("student无参构造器");
}
public Student(String name, int age) {
super(name, age);
System.out.println("student有参构造器");
}
- 创建一个Student对象,并初始化
Student s = new Student("SS", 21);
结果:
person有参构造器
student有参构造器
- 创建一个Student对象,不提供初始化
Student s = new Student();
结果:
person无参数构造器
student无参构造器
结论一:创建子类对象时,无论是否初始化,都会先调用父类的构造器,在调用子类构造器。
注意:再注释掉子类含参构造器的super()语句后,创建子类对象并初始化时,先调用的是父类的无参构造器。
public Student() {
super();
System.out.println("student无参构造器");
}
public Student(String name, int age) {
// super(name, age);
System.out.println("student有参构造器");
}
Student s = new Student("SS",21);
结果:
person无参构造器
student有参构造器
除了构造器,static代码块的执行顺序也是常考内容。我也做了些测试。
再Person类中加入static代码块与非static代码块
//person类中的代码块
static {
System.out.println("personStatic代码块2");
}
static {
System.out.println("personStatic代码块1");
}
{
System.out.println("person非static代码块1");
}
//student类中的代码块
static {
System.out.println("studentStatic代码块1");
}
{
System.out.println("student非Static代码块1");
}
创建对象,并观察结果
personStatic代码块2
personStatic代码块1
studentStatic代码块1
person非static代码块1
person有参构造器
student非Static代码块1
student有参构造器
结论二:无论是子类还是父类的,static代码块最先执行:先父类再子类。然后执行父类的非static代码块、构造器,最后执行子类的非static代码块、构造器。
结合上面两个小测试和结论,可得出以下执行顺序:
1.父类static代码块
2.子类static代码块
3.父类非static代码块
4.父类构造器
5.子类非static代码块
6.子类构造器
当同一级别中含有多个代码块时,按照书写顺序执行。