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

这篇博客深入探讨了Java中构造器与继承时方法调用的细节。通过实例代码解释了在子类构造器中调用父类构造器与方法时,如何处理返回值,特别是在涉及`try-catch-finally`块时的返回值逻辑。文章揭示了在执行`finally`块后,返回值并不会被覆盖,而是保持在`try`块中计算的结果。这展示了Java中方法调用和控制流的微妙之处。
摘要由CSDN通过智能技术生成

题目:

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

}

}

设置断点:

a408cf1b0045c292217f7d1c7504d05e.pnga597eb1b5297bfe9d29713a3a9f3912c.png

Debug:

首先是到new B().getValue();

接着是调到B的构造方法,

a3a7100bb161aa980ca559eeb6d1a10e.png

super(5)表明调用了父类A的构造方法,

接着是调到父类构造方法去了,要执行setValue()方法,我天真地是调用A的setValue(),然而,现实是:

68a75f433234240abac027c96524275d.png

执行了B类的setValue,原因是我们目前是在执行B类的构造方法,所以如果A类和B类有相同的方法名,会优先调用B的

5834f3900ccc4981d49f1616923f0310.png

经过这个过程以后,A的成员value为10

B类构造方法里面第一个super(5)总算执行完,接下来是setValue(getValue()-3)啦

97fa339c824d389ec8c684b88c81ca46.png

B类中没有getValue()这个方法,因此去调用了A类中的,

e34db5c258194840e556978fa84c2340.png

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

bd07b82d323c9018a60c846ae6c216b1.png

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

cbedfff512cb4efe790a1f259bf140f1.png

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

e7bdf1103041f1543181a5ed413080c5.png

3bb86ccc736a98392f40e130a24efa29.png

变成了22

00839b8dfe52e3db4a3cd241278db1f0.png

514221161620c9537b4fddff9ff8c159.png

打印出了22

524eb335fcfc3b91fe10ea20539534f6.png

cf6efb531c785bab4fb229539caf77a7.png

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

}

}

输出的结果是这样子的:

3fa0391d2fa0e0909cf4ee97ff03a2f9.png

所以说,返回的结果一开始在try{}里执行的时候已经返回好结果存起来了,执行finally后回去,只是为了把值取出来

我们再回到setValue(getValue()-3)这里,刚刚说了,getValue()这里最终的结果是11

接着是执行了B类的setValue(getValue()-3),

即setValue(8)

接着去执行super.setValue(2*value),

7872cb2988662d92abfc7b4136ccdb9e.png

变为了16

然后回到Main方法中的new B().getValue();由于B中没有getValue(),又去用A类那里的,

dbccde9c419d8e8dcf13783e20c8ea57.png

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

c4724a5b7ddc4c02edc6c34c62375dfb.png

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

748897486b0acfd0936dd4c3fe9fe103.png

60d184d8584fed39170230cf457e2633.png

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

26c396777f3ceefa2b5906cd2a7c4f93.png

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值