
public class Main { static class Father { private int mOney= 1; public Father() { this.mOney= 2; this.showMoney(); } public void showMoney() { System.out.println("I am father, I have $" + this.money + "."); } } static class Son extends Father { private int mOney= 3; public Son() { this.mOney= 4; this.showMoney(); } @Override public void showMoney() { System.out.println("I am son, I have $" + this.money + "."); } } public static void main(String[] args) { final Son son = new Son(); System.out.println("I am son, I have $" + son.money + "."); } } 输出结果
I am son, I have $0. I am son, I have $4. I am son, I have $4. 后面两行我都能理解,但是第一次输出时为什么 money 字段是 0 ?
谢谢
1 Hurriance 2021 年 7 月 28 日 执行子类的初始化函数的时候,先会去执行父类的初始化函数,其中就会执行 showMoney(),其实父类、子类也有 showMoney(),但是因为你是子类调用栈过来的,所以直接调用子类的 showMoney(),但是此时子类的 money 还没初始化,默认值为 0,即输出 0 |
2 qping 2021 年 7 月 28 日 先初始化父亲, 调用了 showMoney() , showMoney 方法被子类重写了, 调用的是儿子的 showMoney , 儿子的 money 还没赋值,所以是 0 |
3 zhangshine 2021 年 7 月 28 日 搜索“Java 类的初始化顺序” |
4 AlkTTT 2021 年 7 月 28 日 你这两个类都是静态的, 执行顺序为: 父类构造方法 -> 父类 showMoney -> 子类重写了 showMoney,所以调用子类的 showMoney(此时子类的参数还没执行构造方法,money 为 0) |
5 dinghmcn 2021 年 7 月 28 日 如果子类没有重写 showMoney()输出的是什么? |
6 Aruforce 2021 年 7 月 28 日 尽管 Son 和 Father 都有 money 。。但这是两个 money 。。。 第一个输出的 money 是在 Father 类初始化时尚未初始化的 Son 的 money... 而这个值应该是 0 虽然你直觉可能觉得是 3... 在 Father 的初始话代码执行的时候... 实际上 son 的 mOney=3 尚未执行。。所以默认值 0 |
7 NeroKamin 2021 年 7 月 28 日 第一个 money 是执行 Father 构造方法时打印的 Son 类实例中的 money 字段,此时其值为初始零值 |
9 admol 2021 年 7 月 28 日 在父类的构造方法、showMoney 方法、子类的构造方法、showMoney 方法里面分别打上断点,可以观察到执行输出顺序; |
10 songkaizong 2021 年 7 月 28 日 这道题出自《深入理解 Java 虚拟机》 8.3 小节。 为了加深理解,笔者又编撰了一份“劣质面试题式”的代码片段,请阅读代码清单 8-10,思考运行后会输出什么结果。 输出两句都是“I am Son”,这是因为 Son 类在创建的时候,首先隐式调用了 Father 的构造函数,而 Father 构造函数中对 showMeTheMoney()的调用是一次虚方法调用,实际执行的版本是 Son::showMeTheMoney()方法,所以输出的是“I am Son”,这点经过前面的分析相信读者是没有疑问的 了。而这时候虽然父类的 money 字段已经被初始化成 2 了,但 Son::showMeTheMoney()方法中访问的却 是子类的 money 字段,这时候结果自然还是 0,因为它要到子类的构造函数执行时才会被初始化。 |
11 Cusmate 2021 年 7 月 28 日 via Android 楼主所有发的帖子都是在问问题,而且挺频繁的。 |
12 Newyorkcity OP @Hurriance @qping @songkaizong =2 的那个 this 是谁?是 Father 实例,那接下来那个 showMoney 的调用者也应该是 Father 实例,它却用了重写的函数?那为啥字段赋值的时候它不用重写的字段? |