有没有一种方法可以在Java中禁用短路求值?

13

假设我有这样的代码:

boolean ret = a() && b() && c() && d() && e();
通常情况下,只有在a()-d()的所有调用返回true时,才会调用e()。是否可能有一些编译器或JVM选项可以禁用短路评估,因此始终调用e(),而不管其他函数的结果如何?
基本上,我正在对一个巨大系统进行UAT测试,并且需要测试e(),但是设置确保所有a()、b()等都返回true的环境和场景非常麻烦...
编辑:好吧,我想使用位与而不是逻辑与可能提供某种解决方法,但理想情况下,我正在寻找不需要对源代码进行任何更改的解决方案。由于正式和技术原因(如我所述,系统很大,我们需要在分段区域之间推广和部署代码并获得签名),这仅用于测试,生产版本需要启用惰性评估(即使用&&)。
事后总结:
- “正确”的答案是:没有。 - “有用”的答案是:您可以将&&更改为&。 - “我最终做的”答案是:远程调试系统,在表达式上设置断点并告诉eclipse运行e()。

7
请使用单个字符,而非双个字符。 - Marko Topolnik
1
哎呀!你没有编译器来根据你的需求修改代码后重新构建吗? - devnull
1
@devnull:根据环境的不同,修复设置并重新运行测试可能需要相当长的时间,因此一次性收集所有有缺陷的前提条件可能是一个巨大的优势...这可能是非短路评估的几个好用例之一。 - Gyro Gearless
你为什么想要这样做?如果你想测试 e(),为什么不完全将其与此 if 条件分开来测试呢? - Richard Tingle
2
实际上,我对这个设计有点怀疑。除此之外...为什么你不能单独测试 e(),你为什么觉得需要呢?为了测试目的,你应该设置一个场景,使得所有其他情况都返回 true。这可能涉及模拟对象或其他注入值,但你仍然应该找到一种方法来做到这一点。请注意,暂时禁用逻辑意味着你没有测试部署到生产环境的代码(因为该方法运行不同的代码)。 - Clockwork-Muse
@Clockwork-Muse e()已经在集成测试中进行了测试,其余的部分都被设置为返回true。然而,e()也依赖于许多其他需要 stub(桩) 的东西。所以,正如我所提到的,这是一个庞大的系统,唯一确定其是否正常工作的方法是在模拟生产环境的环境中运行它。然而,有些情况非常难以复制。 - Kranach
3个回答

20
为了禁用短路,使用单个 "&" 或 "|" 而不是两个:
boolean ret = a() & b() & c() & d() & e();

很好的简短明了的回答,还附带了一个例子……正是我所需要的。 - AmyW

14

这个建议非常有效 - 以下是解释为什么它有效:

boolean ret = a() && b() && c() && d() && e();

这个调用对方法返回的值使用逻辑与运算。它知道只要有任何一个结果是假,那么最终结果就是假,因此它可以立即返回。'懒惰求值'是一种标准的计算机优化方法,用于避免执行不必要的处理。

boolean ret = a() & b() & c() & d() & e();

这是使用位运算符替换逻辑运算符,如果作用于整数,则会将整数的所有位进行 and 操作。而在布尔类型的情况下,只有真或假的值,但它仍会被视为算术表达式,因此表达式的所有部分都将被计算。

所以对于布尔值,& 和 && 给出相同的逻辑结果,但它们在内部处理方式不同,这恰好符合您要寻找的行为。


3

没有编译器或JVM选项可以改变布尔表达式求值的语义。

如果您无法修改源代码,可能的(虽然不保证)选项包括:

  • 通过精心设置前提条件创造性地重现所需测试的条件。
  • 使用模拟对象。
  • 篡改编译器。
  • 篡改JVM。
  • 调整字节码。

抱歉,这些都比编译器/JVM选项或修改源代码更困难。此外,最后三个选项(以及请求的编译器/JVM选项或修改源代码)违反了正确的测试协议,即不修改正在测试的内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接