题目:
public class Testvaluein {
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);
}
}
public static void main(String[] args) {
System.out.println(new B().getValue());
}
}
设置断点:
Debug:
首先是到new B().getValue();
接着是调到B的构造方法,
super(5)表明调用了父类A的构造方法,
接着是调到父类构造方法去了,要执行setValue()方法,我天真地是调用A的setValue(),然而,现实是:
执行了B类的setValue,原因是我们目前是在执行B类的构造方法,所以如果A类和B类有相同的方法名,会优先调用B的
经过这个过程以后,A的成员value为10
B类构造方法里面第一个super(5)总算执行完,接下来是setValue(getValue()-3)啦
B类中没有getValue()这个方法,因此去调用了A类中的,
A类的成员value成功变成了11,并返回value,所以getValue这个时候已经返回了value为11;
没有什么异常,所以跳过catch,直接执行了finally
因为还在执行B类的构造方法,所以优先是执行了B类的setValue,
变成了22
打印出了22
再到return value:这个value是22???
并不是!!
在try语句中,在执行return语句时,要返回的结果已经准备好了,然后程序才跑去finally那里游一圈。去之前,try中先把要返回的
value存放到了特定的地址,游完finally之后,再去那个地址把value取出来,所以游完又去了return value那里。
所以,即使我在finally那里改变了value的值,它也不会返回给A类的成员value,getValue()的结果仍然是11,我去掉了子类B弄了个简化版的
public class Testfina {
static class A{
private int value;
public A(int value) {
setValue(value);
}
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+1);
System.out.println(value);
}
return value;
}
}
public static void main(String[] args) {
System.out.println(new A(4).getValue());
}
}
输出的结果是这样子的:
所以说,返回的结果一开始在try{}里执行的时候已经返回好结果存起来了,执行finally后回去,只是为了把值取出来
我们再回到setValue(getValue()-3)这里,刚刚说了,getValue()这里最终的结果是11
接着是执行了B类的setValue(getValue()-3),
即setValue(8)
接着去执行super.setValue(2*value),
变为了16
然后回到Main方法中的new B().getValue();由于B中没有getValue(),又去用A类那里的,
变为17,return,getValue()保存为17,接着又去到finally那里游一游
又是setValue(value),现在在执行的是B的构造方法,this当然是指去了B的啦,
然后又是回来把value print出来,
变成了34,然后还是跳去了return这里,把之前存好的结果取出来 ,
完成,返回17,main方法最终打印了17。