实在是服了自己,子类初始化调用父类无参构造这种初学者都应该知道的事,我给忘了。
记得当初看书的时候各种概念抄在笔记本上,再上机实践,以为一辈子都不会忘,还是给忘了。
这件事说明了两个问题:
1.我没有保持专注。
2.不管记性好坏都必须要复习。
我们知道在Java中,子类初始化的时候(不管是通过有参构造还是无参构造),如果继承有父类,都会先去调用父类
的无参构造。
这个没有问题,但是如果在父类和子类中都有static代码块和普通代码块,他们的执行先后顺序又是怎样的呢?先来看一段代码:
A类
1 package com.test; 2 3 /** 4 * @author zhangxingrui 5 * @create 2019-03-24 21:00 6 **/ 7 public class A { 8 9 static { 10 System.out.println("我是A的static代码块"); 11 } 12 13 { 14 System.out.println("我是A的普通代码块"); 15 } 16 17 public A(){ 18 System.out.println("我是A的构造方法"); 19 } 20 21 }
B类
1 package com.test; 2 3 /** 4 * @author zhangxingrui 5 * @create 2019-03-24 21:01 6 **/ 7 public class B extends A { 8 9 static { 10 System.out.println("我是B的static代码块"); 11 } 12 13 { 14 System.out.println("我是B的普通代码块"); 15 } 16 17 public B(){ 18 System.out.println("我是B的构造方法"); 19 } 20 21 }
Main类
1 package com.test; 2 3 /** 4 * @author zhangxingrui 5 * @create 2019-03-24 21:00 6 **/ 7 public class Main { 8 9 public static void main(String[] args) { 10 B b = new B(); 11 System.out.println("---我是可爱的分割线---"); 12 B b2 = new B(); 13 } 14 15 }
好的,代码如上,现在来看程序执行结果:
可以看到,执行顺序是:
A的静态代码块 》B的静态代码块》A的普通代码块》A的构造方法》B的普通代码块》B的构造方法;
同时B被new了两次,但是静态代码块只执行了一次。。。
这说明了啥,说明了A不是在new的时候被执行的,而是在JVM将class文件装载进入内存的时候就办了(JVM将class加载到内存以后会做很多
动作,比如验证、链接、解析等等)。
而普通代码块和构造方法都是在实例化对象的时候才被执行的。
同时也验证了上面说的,子类在初始化的时候会调用父类的无参构造。