我想知道Java如何处理以下场景:
假设我有一个名为Debug的类,它看起来像这样:
public class Debug
{
private static final boolean isAssertEnabled = true;
public static void assertTrue(boolean b, String errorMessage) {
if (isAssertEnabled) {
if (!b) {
throw new RuntimeException(errorMessage);
}
}
}
}
并假设我的代码有一个看起来像这样的调用:
...
Debug.assertTrue((x + y != z) && (v - u > w), "Some error message");
....
我有几个问题:
谢谢你的帮助!
答案 0 :(得分:6)
布尔表达式的评估不应该被编译掉 - 至少是由javac编译。
即使Debug
类文件当前对值没有任何作用,谁会说在执行时会出现这种情况?
使Debug类编译后(通过使isAssertEnabled
静态),javac仍然包含代码 - 但我希望JIT编译器将其删除(尽管你应该看到question Peter referenced)。是否可以将方法内联到任何内容,我不确定。同样,如果JIT编译器可以这样做,并且 if 它意识到评估参数不会产生任何副作用,它可能会避免评估。不过,我不会亲自编写代码。
答案 1 :(得分:2)
为什么要尝试构建Java本身提供的内容?
The assert
keyword完全符合您的要求:可以打开和关闭它(在每个包级别上)执行,并且在禁用断言时避免对布尔表达式求值。
答案 2 :(得分:1)
这让我想起了Log4j的“isTraceEnabled()”,“isDebugEnabled()”等等。必须在if语句中明确地修改日志语句,以避免不必要的日志语句评估。
if(logger.isDebugEnabled() {
logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
}
请参阅“效果”
下的here