这个
public class test
{
public static void main(String[] args)
{
Object o = null;
assert o != null;
if(o != null)
System.out.println("o != null");
}
}
打印出“o != null”; 1.5_22 和 1.6_18。编译器错误?注释掉断言可以修复它。当断言被禁用时,字节码似乎直接跳转到打印语句:
public static main(String[]) : void
L0
LINENUMBER 5 L0
ACONST_NULL
ASTORE 1
L1
LINENUMBER 6 L1
GETSTATIC test.$assertionsDisabled : boolean
IFNE L2
ALOAD 1: o
IFNONNULL L2
NEW AssertionError
DUP
INVOKESPECIAL AssertionError.<init>() : void
ATHROW
L2
LINENUMBER 8 L2
GETSTATIC System.out : PrintStream
LDC "o != null"
INVOKEVIRTUAL PrintStream.println(String) : void
L3
LINENUMBER 9 L3
RETURN
L4
我不知道“讨厌”。 你能给出一些代码的真实例子吗? 你的例子看起来很做作。
编辑 - 出于好奇,我输入了程序,编译它并使用 java 1.6.0_16 运行它。 对我来说没有明显的编译器错误:
可以在运行时启用和禁用断言。如果您使用 -ea-switch (用于启用断言)执行代码,则断言应该起作用:
java -ea my.class
JVM 正在优化 if (o != null) 子句,因为您已经断言 o 永远不会为 null。
断言在运行时默认不启用,通常用于验证代码是否满足某些约定,例如您只想确保某个对象永远不会为空(例如,避免空指针异常)。正是因为这个“契约”,编译器才能优化 if (o != null) ,因为它知道这种情况永远不会发生。
由于它们通常在运行时不启用,因此请将它们视为帮助开发一段代码而不是运行时错误检查机制。