原始版
以下程序执行的结果是:
class X{
Y y=new Y();
public X(){
System.out.print("X");
}
}
class Y{
public Y(){
System.out.print("Y");
}
}
public class Z extends X{
Y y=new Y();
public Z(){
System.out.print("Z");
}
public static void main(String[] args) {
new Z();
}
}
记住:最后才执行的是自己的main方法,前面就涉及到类的加载
父子都需要先打扫干净自己的屋子(执行完所有的除了构造方法和普通方法),静态代码块。先父后子
此时因为main在Z这里,而Z继承了X,就是执行① Y y=new Y();,直接执行的是Y的构造方法。 然后输出第一个Y。
因为还在加载父类,所以我们在子类中会调用父类,所以我们执行父类的构造方法。
父类所有的东西都加载完毕。
子类一开始new 了一个Y,执行构造方法
main中new 了一个自己,执行自己的构造方法。
升级版:
class X {
{System.out.print("1\t开始执行父类X中的静态代码块");}
Y y=new Y(); //new 了一个Y,执行Y的构造方法
public X(){
System.out.print("父类X的构造方法\n");
}
{System.out.print("2\t父类X加载完毕,最后一个代码块\n");}
}
class Y{
public Y(){
System.out.print("\nnew 一个Y就执行构造方法,输出该语句\n");
}
}
public class Z extends X {
{System.out.print("3\t执行子类Z的静态代码块");}
Y y=new Y(); //new 了一个Y,执行Y的构造方法
public Z() {
System.out.print("\n在main方法中,new 了一个子类Z就执行构造方法,输出ZZZ");
}
public static void main(String[] args) {
new Z();
}
{System.out.print("4\t执行完子类的所有静态方法,但是还没有初始化构造方法(还没有人调用,也没有子类去调用我)");}
}
console:
1 开始执行父类X中的静态代码块
new 一个Y就执行构造方法,输出该语句
2 父类X加载完毕,最后一个代码块
父类X的构造方法
3 执行子类Z的静态代码块
new 一个Y就执行构造方法,输出该语句
4 执行完子类的所有静态方法,但是还没有初始化构造方法(还没有人调用,也没有子类去调用我)
在main方法中,new 了一个子类Z就执行构造方法,输出ZZZ
Process finished with exit code 0
那么,我们再加上一个子类会怎么样呢?
public class K extends Z{
public K(){
System.out.println("\n这是K的构造方法");
}
public static void main(String[] args) {
new K();
}
}
console:
1 开始执行父类X中的静态代码块
new 一个Y就执行构造方法,输出该语句
2 父类X加载完毕,最后一个代码块
父类X的构造方法
3 执行子类Z的静态代码块
new 一个Y就执行构造方法,输出该语句
4 执行完子类的所有静态方法,但是还没有初始化构造方法(还没有人调用,也没有子类去调用我)
在main方法中,new 了一个子类Z就执行构造方法,输出ZZZ
这是K的构造方法
结论:
加载完父类的所有东西再去加载自己的东西的。
例如我们要把父类的所有静态方法和构造方法都弄完才能去弄子类的东西。