>讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,当 new 的时候,他们的执行顺序。
先说结论,顺序为:
1. 父类静态变量、
2. 父类静态代码块、
3. 子类静态变量、
4. 子类静态代码块、
5. 父类非静态变量(父类实例成员变量)、
6. 父类构造函数、
7. 子类非静态变量(子类实例成员变量)、
8. 子类构造函数。
代码举例说明:
A.java
```
public class A {
int a1 = 8;
static int a3 = getA3();
int a2 = getA2();
{
int a3 = 9;
System.out.println("top of A() a1=" + a1 + " a2=" + a2 + " a3=" + a3);
}
public A() {
this(66);
System.out.print("A 构造函数\n");
}
{
System.out.println("below A()..has start");
}
public A(int num) {
System.out.print("A 带参数构造函数: " + num + "\n");
}
static {
System.out.println("I`m a static {} from class A..");
}
int getA2() {
System.out.println("getA2..");
return 7;
}
static int getA3() {
System.out.println("getA3..");
return 7;
}
public void methodA() {
System.out.println("methodA");
}
}
```
B.java
```
public class B extends A {
int b1 = 0;
int b2 = getB2();
static int b3 = getB3();
{
int b3 = 5;
System.out.println("top of B() b1=" + b1 + " b2=" + b2 + " b3=" + b3);
}
public B() {
this(33);
// super(44);//添加super语句,会导致实例化时直接执行父类带参数的构造函数
System.out.print("B 构造函数\n");
}
public B(int num) {
// 添加super语句,会导致实例化时直接执行父类带参数的构造函数
// 前提是带参数的构造函数B会被运行(new实例化或this)
// super(77);
System.out.print("B 带参数构造函数:" + num + "\n");
}
{
System.out.println("below B()..has start");
}
static {
System.out.println("I`m a static {} from class B..");
}
int getB2() {
System.out.println("getB2..");
return 33;
}
static int getB3() {
System.out.println("getB3..");
return 7;
}
@Override
public void methodA() {
System.out.println("methoaA int class B");
super.methodA();
}
}
```
mymain.java
```
public class mymain {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("main app run..");
B b = new B();
// B b = new B(22);
b.methodA();
}
}
```
综合结论,一个类的实例化过程:
1. 首先会执行类中static代码块(不管代码块是否在类的开头还是末尾处),如果这个类有父类,同样会优先查找父类中的static代码块,然后是当前类的static。
2. 然后会从父类的第一行开始执行,直至代码末尾处,中间不管是有赋值还是method调用,都会按顺序一一执行(method),普通代码块{ }...
3. 其次才是父类的构造函数,执行带参数或不带参数的构造函数,依赖于实例化的类的构造函数有没有super父类的带参或不带参的构造函数,上边试验二三已经证明。
4. 然后会从子类(当前类)的第一行开始执行,直至代码末尾处,中间不管是有赋值还是method调用,都会按顺序一一执行(method),普通代码块{ }...
5. 其次会是子类(当前类)的构造函数,按顺序执行。
6. 最后是类方法的调用执行,如果子类覆盖了父类的method,执行时会先执行子类覆盖的method,method内如果有super.method(),才会调用父类的同名method,否则不会。

类的实例化顺序