如何从finally块访问方法的结果值

发布于:2021-01-11 10:47:52

0

68

0

java finally 访问方法

对于任何希望他们能够在返回之前检查堆栈中的值的Java开发人员来说,这是一个好消息,但不是那么好消息。

尽管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 return     if (result == 1337)         log.info("hehehe ;-)");       return result; }

当然,上面的示例是错误的,因为在以前,if (something) return 1andif (something) return 2语句会立即中止方法的执行。为了使用“单返回语句”技术实现相同的目的,我们必须像这样重写代码:

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块,或者您想要访问的不仅仅是结果值,而且您不想重构该方法。

其他方法?

现在轮到你了。您首选的替代方法是什么(带有代码示例?),例如,使用Try monad?还是方面?