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

问题描述 投票:0回答:3

这个

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 eclipse assert
3个回答
1
投票

我不知道“讨厌”。 你能给出一些代码的真实例子吗? 你的例子看起来很做作。

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

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

1
投票

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

java -ea my.class

0
投票

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

断言在运行时默认不启用,通常用于验证代码是否满足某些约定,例如您只想确保某个对象永远不会为空(例如,避免空指针异常)。正是因为这个“契约”,编译器才能优化 if (o != null) ,因为它知道这种情况永远不会发生。

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

© www.soinside.com 2019 - 2024. All rights reserved.