Java断言令人讨厌的副作用 - 编译器错误?

时间:2010-02-17 10:59:39

标签: java eclipse compiler-construction assert

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。编译错误?评论断言修复了它。当断言被禁用时,字节代码似乎直接跳转到print语句:

 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

3 个答案:

答案 0 :(得分:1)

我不知道“讨厌”。你能给出一些代码的真实例子吗?你的例子看起来非常人为。

编辑 - 出于好奇,我输入程序,编译并使用java 1.6.0_16运行它。我没有明显的编译器错误:

  • 启用断言(java -ea test)后,我收到断言错误。
  • 禁用断言(java测试)后,我得到 no 输出。

答案 1 :(得分:1)

可以在运行时启用和禁用断言。如果使用-ea-switch执行代码(对于启用断言),则断言应该起作用:

java -ea my.class

答案 2 :(得分:0)

JVM正在优化if(o!= null)子句,因为你已经断言o永远不会为null。

默认情况下,默认情况下不会启用断言,并且通常用于验证代码是否符合某些合同,例如你只是想确保某个对象永远不会为null(例如,为了避免空指针异常)。正是由于这个“契约”,编译器可以优化if(o!= null),因为它知道这种情况永远不会发生。

由于它们通常在运行时未启用,因此将它们视为有助于开发一段代码而不是运行时错误检查机制。

相关问题