发布于:2021-01-11 10:47:52
0
68
0
对于任何希望他们能够在返回之前检查堆栈中的值的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?还是方面?
作者介绍