java父类子类构造方法及方法的调用

题目:

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());
	}

}

设置断点:

java父类子类构造方法及方法的调用_第1张图片java父类子类构造方法及方法的调用_第2张图片

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类中的,

 

 java父类子类构造方法及方法的调用_第3张图片

A类的成员value成功变成了11,并返回value,所以getValue这个时候已经返回了value为11;

java父类子类构造方法及方法的调用_第4张图片

没有什么异常,所以跳过catch,直接执行了finally

java父类子类构造方法及方法的调用_第5张图片

因为还在执行B类的构造方法,所以优先是执行了B类的setValue,

变成了22

java父类子类构造方法及方法的调用_第6张图片

打印出了22

java父类子类构造方法及方法的调用_第7张图片

java父类子类构造方法及方法的调用_第8张图片

再到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());
  
}
}

输出的结果是这样子的:

java父类子类构造方法及方法的调用_第9张图片

所以说,返回的结果一开始在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类那里的,

java父类子类构造方法及方法的调用_第10张图片

变为17,return,getValue()保存为17,接着又去到finally那里游一游

java父类子类构造方法及方法的调用_第11张图片

又是setValue(value),现在在执行的是B的构造方法,this当然是指去了B的啦,

java父类子类构造方法及方法的调用_第12张图片

然后又是回来把value print出来,

java父类子类构造方法及方法的调用_第13张图片

变成了34,然后还是跳去了return这里,把之前存好的结果取出来 ,

完成,返回17,main方法最终打印了17。

 

你可能感兴趣的:(java)