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

发布于 2024-08-21 16:01:49 字数 826 浏览 9 评论 0原文

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

This

public class test 
{
    public static void main(String[] args) 
    {
        Object o = null;
        assert o != null;
        if(o != null)
          System.out.println("o != null");
    }
}

prints out "o != null"; both 1.5_22 and 1.6_18. Compiler bug? Commenting out the assert fixes it. The byte code appears to jump directly to the print statement when assertions are disabled:

 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冷夜 2024-08-28 16:01:49

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

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

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

I don't know about "nasty". Can you give a real example of some code where this would bite you? Your example looks very contrived.

EDIT - out of curiosity, I typed in the program, compiled it and ran it with java 1.6.0_16. No compiler bug is evident for me:

  • With assertions enabled (java -ea test) I get an assertion error.
  • With assertions disabled (java test) I get no output.
飘过的浮云 2024-08-28 16:01:49

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

java -ea my.class

Assertions can be enabled and disabled at runtime. If you execute your code with the -ea-switch (for enable assertions) the assert should work:

java -ea my.class
甜心小果奶 2024-08-28 16:01:49

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

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

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

The JVM is optimising the if (o != null) clause away because you've already asserted that o is never going to be null.

Assertion are not enabled by default at runtime, and are generally used to validate that code fulfils some contract, e.g. you just want to make sure that a certain object is never going to be null (e.g. to avoid null pointer exceptions). It is because of that "contract" that the compiler can optimise the if (o != null) away, because it knows that this condition will never happen.

As they are generally not enabled at runtime, think of them as helping to develop a piece of code rather than a runtime error checking mechanism.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文