Java的动手动脑(四)
日期:2018.10.18
星期四
博客期:019
Part1:回答为啥会报错
答案:当然会报错啦!因为平常的编程过程中,系统会对我们写的类自动生成一个默认无参形式的构造方法,类似于C++中的体制!这个在你写了构造方法之后,系统就不会再自动为你分配一个无参的构造方法了。所以在图中的Foo类中只有一个带一个int类型参数的构造方法,在调用无参的构造方法时就会报错!
Part 2:运行下列代码,总结以下构造顺序
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package teacherMake; 2 3 class Root 4 { 5 static{ 6 System.out.println("Root的静态初始化块"); 7 } 8 { 9 System.out.println("Root的普通初始化块"); 10 } 11 public Root() 12 { 13 System.out.println("Root的无参数的构造器"); 14 } 15 } 16 class Mid extends Root 17 { 18 static{ 19 System.out.println("Mid的静态初始化块"); 20 } 21 { 22 System.out.println("Mid的普通初始化块"); 23 } 24 public Mid() 25 { 26 System.out.println("Mid的无参数的构造器"); 27 } 28 public Mid(String msg) 29 { 30 //通过this调用同一类中重载的构造器 31 this(); 32 System.out.println("Mid的带参数构造器,其参数值:" + msg); 33 } 34 } 35 class Leaf extends Mid 36 { 37 static{ 38 System.out.println("Leaf的静态初始化块"); 39 } 40 { 41 System.out.println("Leaf的普通初始化块"); 42 } 43 public Leaf() 44 { 45 //通过super调用父类中有一个字符串参数的构造器 46 super("Java初始化顺序演示"); 47 System.out.println("执行Leaf的构造器"); 48 } 49 50 } 51 52 public class TestStaticInitializeBlock 53 { 54 public static void main(String[] args) 55 { 56 new Leaf(); 57 58 59 } 60 }
先显示一下结果:
好了,总结以下顺序:
先是执行静态初始化块,为什么呢?其实就是一个静态数据不同于成员数据的一点,它是先于在系统外部声明构造的,因而会放在最初构造!而其内部也是通过先调用基类(C++概念)[子类]的数据构造,在调用自身的构造;之后的顺序就看你的构造方法是怎么写的了,主要在于声明顺序,在C++里是按顺序先构造基类的成员(内部也是按照声明顺序),Java类似,因为是子类继承父类的成员先构造子类,而且Java不允许多重继承(注意:不是多继承),因而不会有父类的继承顺序(就像老师说的,在Java的“宪法”里,一个“儿子”只准有一个“爹”,哈哈哈),差不多就是父类---->子类的顺序了;再深化一点儿?行吧!我刚刚测试了一下程序,如下图。老师说父类的构造必须先写,我就不信!!!我就要试!!!结果虽然是我败了,但精神可嘉啊!!!至少我清楚的认识到了,老师没有恶意修改Java的”宪法“!嘿嘿!那顺序就是固定的了!(如果觉得不正确,可以留言)
Part 3: 运行代码说明结果
结果如下:
是的,这就是每一次初始化会更新掉之前的存储数据的原因!