Java中if(!foo)和if(foo == false)之间的性能差异(如果有)是什么?

Pop*_*ops 15 java syntax performance

逻辑上,if(!foo)并且if(foo == false)是等价的.它们如何用Java表示?编译后两者在字节码或性能方面有什么区别吗?我无法在JLS中找到答案,搜索提出了很多关于= vs. ==拼写错误和==/equals()行为的结果.(在这种情况下,符号妨碍了我的搜索;对于未来的搜索者,否定运算符,等于假,等于假,而不是条件).

为了阻止CW辩论:这个问题不是要求人们选择哪种变体,哪种变体被认为是更好的风格.我对语言实现的差异感兴趣,所以有一个正确的答案.相关但不完全是骗局:Java中while(x = false)和while(!x)之间的区别?

编辑:

普遍的共识似乎是一个好的编译器应该优化它们到同一个东西.这是有道理的,也是我所怀疑的,但是 - 提出更多的学术问题 - 这种行为实际上是在任何地方强制执行的,还是"仅仅"是合理的事情?

not*_*oop 44

JLS将指定语句所需的行为.但是,它们的实现方式是编译器和JVM的实现细节.

在实践中,任何有价值的编译器都应为这些语句发出相同的字节码.即使没有,JVM也会正确地优化它们.

此外,更好的方法是回答这个问题,使用javap以下方法检查自己:

  1. Test.java使用以下内容编译a :

    class Test {
        void equals(boolean f) {
            if (f == false) {}
        }
        void not(boolean f) {
            if (!f) {}
        }
    }
    $ javac Test.java
    
    Run Code Online (Sandbox Code Playgroud)
  2. 解组它:

    $ javap -c Test
    Compiled from "Test.java"
    class Test extends java.lang.Object{
    Test();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   return
    
    void equals(boolean);
      Code:
       0:   iload_1
       1:   ifne    4
       4:   return
    
    void not(boolean);
      Code:
       0:   iload_1
       1:   ifne    4
       4:   return
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

更新:回答关于"学术"问题的问题.如上所述,JLS只关注行为.标准中没有任何内容实际指定它应该如何实现(嗯,JVMS提供了很多指导).

只要编译器保留相同的相同行为,编译器就可以自由地实现它,可能会有不同的运行时性能.

  • `javap -c`反汇编,它不反编译. (4认同)

Gre*_*ith 12

编译器应在内部解析相同的代码,因此没有区别.

  • 如果没有任何参考,证明等(即使是真的),也不要赞成自由声明. (5认同)