Test.main()函数执行后的输出是什么?
class Test { public static void main(String[] args) { System.out.println(new B().getValue()); } static class A { protected int value; public A (int v) { setValue(v); } public void setValue(int value) { this.value= value; } public int getValue() { try { value ++; return value; } finally { this.setValue(value); System.out.println(value); } } } static class B extends A { public B () { super(5); setValue(getValue()- 3); } public void setValue(int value) { super.setValue(2 * value); } } }
本人看到此题,读着读着就一脸懵逼了,但是经过查阅资料以及大哥们的解答,学习到了很多,在此记录一下此题,帮助大家共同学习和进步。
- 在main()函数中,首先new B()实例,此时B类中的无参构造函数现实的调用了父类A的带参构造函数。
- 在父类A中的带参构造函数中,又调用了setValue(v)方法,但是在父类A和子类B中都有setValue(v)方法,并且此时正在初始化的是一个子类B的实例对象,根据java多态特性,此时会调用的是子类B中的setValue(v)方法,而不是父类A中的setValue(v)方法。
- 而在子类的setValue()方法又显示的调用了父类的setValue()方法,将父类中的value值设置为了2*5=10
- 继续执行B类构造方法中的setValue(getValue() - 3)方法。
- 在上面方法中先执行getValue()方法,而在子类B中,没有重写父类的getValue()方法,因此调用的是父类的getValue()方法。在父类的getValue()方法中,分为如下几步:
- 在执行getValue()方法之前,value值已经被设置为10。
- value++后,value的值为11
- 将value值return返回出去
- 紧接着执行finally中的代码,所以暂时性的将上一步中的value值存储起来。等到finally代码块执行完成后再正真的将value值返回出去。
- 在finally中,又执行了setValue()方法,此时执行的也是子类B中的setValue()方法,因为此时我们正在初始化的是子类B的实例对象。(Java运行时多态)
- 而在子类B中的setValue()方法中又显示的调用了父类A中的setValue()方法,此时的value值又被设置为了2*11=22
- 紧接着执行finally代码块中的输出语句,打印出value值为22
- 紧接着将try语句中的return语句进行返回,返回的是暂存的value值11
- 返回值11之后,继续执行子类B中的setValue()方法,此时setValue()方法中的参数值为11-3=8,在执行setValue()方法时,显示的调用了父类的setValue()方法,并将value值设置为了2*8=16
- 终于,我们执行完了main()方法中的new B()方法,此时的value值为16,紧接着调用main()方法中的new B()方法的后续的方法getValue()方法
- 调用getValue()方法,子类B中没有重写父类A的getValue()方法,所以实际上执行的时父类中的getValue()方法,步骤如下:
- 在执行getValue()方法之前,value值已经被设置为16。
- value++后,value的值为17
- 将value值return返回出去
- 紧接着执行finally中的代码,所以暂时性的将上一步中的value值存储起来。等到finally代码块执行完成后再正真的将value值返回出去。
- 在finally中,又执行了setValue()方法,此时执行的也是子类B中的setValue()方法,因为此时我们正在初始化的是子类B的实例对象。(Java运行时多态)
- 而在子类B中的setValue()方法中又显示的调用了父类A中的setValue()方法,此时的value值又被设置为了2*17=34
- 紧接着执行finally代码块中的输出语句,打印出value值为34
- 紧接着将try语句中的return语句进行返回,返回的是暂存的value值17
- 最后在main方法中打印返回的值,返回的值为17,打印17
- 最后控制台上的打印结果为22 34 17
具体流程就到此结束了,是不是感觉很麻烦,但是实际上很简单,相信你也看出来了,实际上就是对多态的理解,麻烦的就是调用过来调用过去就晕了,只要理清思路还是很简单的。
(注意:try语句中的返回值会先暂时保存,等待finally代码块执行完成后再将暂存的值返回,finally代码块中的代码不会影响暂时存储的返回值哦!)
本题的解析主要时参考了牛客网用户<可乐芒果柠檬>的解析,如有意见,请联系我删除。