尽管JVM是基于堆栈的计算机 ,但Java语言实际上并没有为您提供任何访问该堆栈的方法。 即使有时,在极少数情况下,它也会非常有用。
一个例子
方法结果值放在堆栈中。 如果查看以下示例:
public int method() {if (something)return 1;...if (somethingElse)return 2;...return 0;
}
如果我们忽略了停机问题 ,错误处理,以及其他学术讨论,我们可以说,上述方法将“肯定”返回的任何值1
, 2
或0
。 并且该值在退出该方法之前被放入堆栈中。
现在,有时,仅当返回给定结果值时才采取一些措施可能是一个用例。 然后,可能会诱使人们开始关于是否有多个return
语句为EVIL™的古老争论 ,而整个方法应该这样写:
public int method() {int result = 0;if (something)result = 1;...if (somethingElse)result = 2;...// Important action here prior to returnif (result == 1337)log.info("hehehe ;-)");return result;
}
当然,上面的示例是错误的,因为以前, if (something) return 1
而if (something) return 2
语句则立即中止方法执行。 为了使用“单返回语句”技术实现相同的目的,我们必须像这样重写代码:
public int method() {int result = 0;if (something)result = 1;else {...if (somethingElse)result = 2;else {...}}// Important action here prior to returnif (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 returnfinally {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 returnfinally {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
块,或者您想要访问的不仅仅是结果值,而且您不想重构该方法。
其他方法?
现在轮到你了。 您首选的替代方法是什么(带有代码示例?),例如,使用Try monad? 还是方面?
翻译自: https://www.javacodegeeks.com/2015/05/how-to-access-a-methods-result-value-from-the-finally-block.html