java 栈 返回值_如何在finally块中访问返回值

本文探讨了在Java中如何在finally块中访问方法返回值的问题,提供了一种通过设置中间变量并在finally块中检查的技巧,同时讨论了其他可能的解决方案,如额外的方法调用和可读性更强的代码结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如何在finally块中访问返回值

Published:

11 Jun 2015

Category:

尽管JVM是基于栈的虚拟机,但Java语言却不允许你去访问这个栈。但其实在某些场景下(尽管是不太常见),这个功能是非常实用的。

示例

方法返回的结果会存储在栈上。看下这段代码:

public int method() {

if (something)

return 1;

...

if (somethingElse)

return 2;

...

return 0;

}

如果我们不考虑[停机问题](http://it.deepinmind.com/%5BHalting%20problem%5D(http://en.wikipedia.org/wiki/Halting_problem),错误处理,以及其它学术上的问题,可以这么说,上述方法“肯定”会返回0,1或者2。并且这个值会存储在栈上,然后才会跳出这个方法。

有时候还会有这么一种情况,就是希望在返回某个特定值的时候执行特定的操作。大家可能又会为 该不该使用多重return语句陷入无止境的口水仗了,这个方法就会变成这样:

public int method() {

int result = 0;

if (something)

result = 1;

...

if (somethingElse)

result = 2;

...

// Important action here prior to return

if (result == 1337)

log.info("hehehe ;-)");

return result;

}

当然了,上面的方法是有问题的,因为如果if (something) return 1 执行了,那么 if (something) return 2就不会被执行了。为了能达到原来“单一return语句”那样的效果,我们得把代码重写成这样:

public int method() {

int result = 0;

if (something)

result = 1;

else {

...

if (somethingElse)

result = 2;

else {

...

}

}

// Important action here prior to return

if (result == 1337)

log.info("hehehe ;-)");

return result;

}

当然了,关于这个方法 是否应该使用大括号以及缩进级别 还可以再吵上几天,不过这只是空费唇舌而已。

从栈中获取返回结果

其实我们想做的事情就是在原来的实现中,在返回结果之前的时候,检查下栈内的结果是什么,下面是用Java写的伪代码:

public int method() {

try {

if (something)

return 1;

...

if (somethingElse)

return 2;

...

return 0;

}

// Important action here prior to return

finally {

if (reflectionMagic.methodResult == 1337)

log.info("hehehe ;-)");

}

}

好消息就是,这个确实能实现!一个简单的小技巧就能实现这个功能:

public int method() {

int result = 0;

try {

if (something)

return result = 1;

...

if (somethingElse)

return result = 2;

...

return result = 0;

}

// Important action here prior to return

finally {

if (result == 1337)

log.info("hehehe ;-)");

}

}

不过坏消息就是,你可千万别忘了给返回值赋值啊。不过不管怎么说,这项技术还是挺有用的,它可以实现“方法栈访问”,尽管Java语言并不允许我们这么做。

当然了

不过,当然你还可以通过下面这种方式来解决,虽然有点烦人:

public int method() {

int result = actualMethod();

if (result == 1337)

log.info("hehehe ;-)");

return result;

}

public int actualMethod() {

if (something)

return result = 1;

...

if (somethingElse)

return result = 2;

...

return result = 0;

}

在很多时候,这种方案的确是要更好一些(可读性更强)。不过有时候可能你想要在finally块中做的并不止是打印日志这么简单,又或者你想访问的也不止是result的值,而你又不想再重构这个方法,这时候这项技巧就派上用场了。

还有别的方法吗

现在该看你的了。你有什么推荐的可选方案吗?比如说,使用try monad,或者是切面?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值