有这样一段程序,看看它会输出什么结果
代码装载自:http://blog.csdn.net/xiaokang123456kao/article/details/75195045
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);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
输出:
22
34
17
这段程序咋一看没什么特殊的,但是细细分析下来,发现想搞清楚它的运行过程还真不简单。通过Eclipse单步调试,得出其运行流程如下:(序号1、2就表示运行次序)
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);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
通过对上述程序的分析,可以得到如下信息:
1、当子类对象调用一个方法时,会优先在子类中查找,然后才回去父类中查找。如果子类调用了父类的方法method1,而method1又调用了method2,那么这个method2还是会优先在子类中查找,找不到才会去父类中查找。
2、如果子类继承了父类的成员变量(前提是可以继承public和protected),而子类没有显示覆盖该成员变量,那么子类访问到的成员变量和父类访问到的成员变量是同一个变量。任何一个修改后都会影响到另一个。
3、try中的return会在finally语句块之后运行,如果finally语句块中有return语句,那个就直接返回这个return值。如果没有,就返回try中的return值(finally块中的任何非return操作都不会影响到try中的return值)。、
个人总结:
为什么会有3个输出
1.new B().getValue()有两个输出
new B(),首先调用父类构造函数,在调用自己的构造函数。会输出一次System.out.println(value);
getValue()时会调用A的getValue()函数,输出一次System.out.println(value);
2.System.out.println(new B().getValue())会输出一次
执行完new B().getValue(),会return一个value=17