本篇博客我们来看一道在牛客上遇到的问题。
我们来看题目:
Test.main()
函数执行后的输出是()
public 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;
} catch(Exception e) {
System.out.println(e.toString());
} finally {
this.setValue(value);
System.out.println(value);
}
return value;
}
}
static class B extends A {
public B() {
super(5);
setValue(getValue() - 3);
}
public void setValue(int value) {
super.setValue(2 * value);
}
}
}
我们来分析一下这段代码的执行结果:
- 首先
new B()
会去执行B的构造方法。
B的构造方法中,第一行为super(5);
,此时回去执行A的构造方法,A的构造方法中调用setValue(int value);
,注意此时由于B重写了该方法,所以执行的是B中的setValue(int value);
,所以会去执行super.setValue(2 * value);
,进而去执行A中的setValue(int value);
方法。传入的参数为2 * 5 = 10
,此时value的值为10。
下面执行B的构造方法中的第二行setValue(getValue() - 3);
,由于B中没有getValue()
方法,所以会去调用A类中的getValue()
方法。try代码块中返回的10 + 1 = 11
,暂时保存在栈中,此时调用finally块中的this.setValue(value);
,同样的会去调用B中的setValue(int value)
方法,执行super.setValue(2 * value)
,传入的为22,此时value被设置为22,执行System.out.println(value);
打印的结果就是22。此时,保存在栈中的11被返回,继续执行setValue(getValue() - 3);
,此时调用setValue(int value)
传入的参数为11 - 3 = 8
,然后在B中的setValue(int value)
方法中执行super.setValue(2 * value);
,调用A类的setValue(int value)方法,传入的参数为2 * 8 = 16
。此时value被设置为16。
到这里,new B()
执行完毕。 - 然后执行
new B().getValue()
。
B中没有getValue()
方法,所以会去执行A类中的getValue()
方法,try块中对value进行自增,value变为17,保存到栈中。然后去执行finally块中的代码,执行this.setValue(value);
会去执行B类中的setValue(int value);
方法,进而执行super.setValue(2 * value);
语句,传入参数为34,此时value被设置为34,然后执行System.out.println(value);
打印的结果就是34。 - 最后主函数打印返回值,即保存在栈中的数据17。
所以该程序运行的结果为:
22
34
17
我们执行一下该代码看一下结果: