我们知道,实例变量初始化和代码块初始化问题在构造函数执行之前。
每个类至少都有一个构造函数,在编译生成字节码时,构造函数会被命名成<init>方法,参数类弄和顺序不变 。
我们知道,java在实例化类之前,必须先实例化其超类,以保存实例的完整性。事实上,这一点是在构造函数中保证的,
构造的函数的第一条语句必须是调用超类的语句或是类中定义的其他函数。如果我们没有显示地调用超类的构造函数,也没有调用类中的其它构造函数,
则编译器会自动为我们生成对超类构造函数的调用。如:
public class Student {
public static void main(String[] args) {
System.out.println(111);
}
}
上面的语句没有显示地调用超类构造函数,但是我们可以查看编译后的字节码,编译器自动为我们生成了调用超类的代码,如下:
上面红色箭头就是调用超类Object类的构造函数。
特别地,如果我们在一个构造函数中调用另外一个构造函数,如下:
public class Student {
private int i;
/**
* 在无参构造函数中调用有参构造函数
* 对于这种情况,只允许在 Student(int i) 中调用超类的构造函数
*/
public Student() {
//super(); //在这里调用父类构造方法会报错,
this(1);
}
public Student(int i) {
this.i = i;
}
public static void main(String[] args) {
System.out.println(111);
}
}
总结:实例化一个类的对象的过程是一个典型的递归过程,实例化类的对象时,会先实例化该类的父类,
如果该父类还有父类,那么会一直往上递归直到Object类,先实例化Object类,再往下递归实例化,直到目标类。
实例化每个类时,遵循如下顺序,先执行实例变量初始化和实例代码块初始化,再执行构造函数初始化。
也就是説,编译器会将实例变量和实例代码块放到类的构造函数中去,并且放到超类的调用构造函数语句之后,构造函数本身代码之前 。
综合实例:
实例变量初始化、实例代码块初始化以及构造函数初始化
//父类
class Foo {
int i = 1;
Foo() {
System.out.println(i); //输出2 ----(1)
int x = getValue();
System.out.println(x); //输出0,根据多态,调用的是子类的getValue(),而此时子类的构造函数还没被调用 ----(2)
}
{
i = 2;
}
protected int getValue() {
return i;
}
}
//子类
class Bar extends Foo {
int j = 1;
Bar() {
j = 2;
}
{
j = 3;
}
@Override
protected int getValue() {
return j;
}
}
public class ConstructorExample {
public static void main(String... args) {
Bar bar = new Bar();
System.out.println(bar.getValue()); //输出2 ----(3)
}
}
我们可以将Foo类的构造函数和Bar类的构造函数等价地分别变为如下形式:
Foo() {
i = 1;
i = 2;
System.out.println(i); //输出2 ----(1)
int x = getValue();
System.out.println(x); //输出0,根据多态,调用的是子类的getValue(),而此时子类的构造函数还没被调用 ----(2)
}
Bar() {
Foo();
j = 1;
j = 3;
j = 2;
}
在通过使用Bar类的构造方法new一个Bar类的实例时,首先会调用Foo类构造函数,因此(1)处输出是2,这从Foo类构造函数的等价变换中可以直接看出。
(2)处输出是0,为什么呢?因为在执行Foo的构造函数的过程中,由于Bar重载了Foo中的getValue方法,所以根据Java的多态特性可以知道,
其调用的getValue方法是被Bar重载的那个getValue方法。但由于这时Bar的构造函数还没有被执行,因此此时j的值还是默认值0,因此(2)处输出是0。
最后,在执行(3)处的代码时,由于bar对象已经创建完成,所以此时再访问j的值时,就得到了其初始化后的值2,这一点可以从Bar类构造函数的等价变换中直接看出。
参考:https://blog.csdn.net/justloveyou_/article/details/72466416