代码之家  ›  专栏  ›  技术社区  ›  Pops Atula

如果有的话,if(!在Java中,如果(fo==false)?

  •  15
  • Pops Atula  · 技术社区  · 15 年前

    逻辑上, if(!foo) if(foo == false) 是等效的。它们是如何用Java表示的?编译后的两个字节码和性能有什么区别吗?我在jls中找不到答案,搜索得到了大量关于=vs.==打字错误和=/equals()行为的结果。(在这种情况下,符号阻碍了我的搜索;对于未来的搜索者,否定运算符等于假,等于假,而不是条件)。

    避免CW辩论:这个问题不是问人们更喜欢哪种变体,或者哪种被认为是更好的风格。我对语言实现的差异感兴趣,所以有一个正确的答案。相关但不完全重复: Difference between while (x = false) and while (!x) in Java?

    编辑:

    一般的共识似乎是,一个好的编译器应该将这些优化到相同的事情上。这是有道理的,也是我所怀疑的,但是——问一个更学术的问题——这种行为实际上是在任何地方强制执行的,还是仅仅是“合理”的行为?

    8 回复  |  直到 12 年前
        1
  •  44
  •   notnoop    15 年前

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

    在实践中,任何值得一试的编译器都应该为这些语句发出相同的字节码。即使没有,JVM也会对它们进行适当的优化。

    另外,回答这个问题的一个更好的方法是检查你自己,使用 javap :

    1. 编译一 Test.java 包含以下内容:

      class Test {
          void equals(boolean f) {
              if (f == false) {}
          }
          void not(boolean f) {
              if (!f) {}
          }
      }
      $ javac Test.java
      
    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
      
      }
      

    更新: 回答你关于“学术”问题的问题。如上所述,JLS只关注行为。标准中没有实际规定应该如何实现的内容(好吧,JVM提供了很多指导)。

    只要编译器保持相同的行为,编译器就可以自由地实现不同的行为,可能具有不同的运行时性能。

        2
  •  12
  •   Dave Jarvis James Eichele    12 年前

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

        3
  •  0
  •   gingerbreadboy    15 年前

    尝试 decompiling the byte code 看看代码看起来有多不同。我猜编译将以几乎相同的方式解决它们,任何细微的差异都将导致可忽略的性能差异。

        4
  •  0
  •   Carl Smotricz    15 年前

    好的,更完整的答案是:

    如果任何编译器为这些变化生成不同的字节码,我会非常惊讶。对于任何感兴趣的人来说,使用拆卸器检查应该足够容易。

    考虑到这两个表达式(很可能)都编译到同一个字节码,我希望在大小或性能上没有差别。

        5
  •  0
  •   Robert Christie    15 年前

    捷豹路虎说

    中的表达式 对if块进行计算,然后 该表达式的结果与 真

    在非案例和比较对象案例中,需要对表达式进行评估,然后将其与true进行比较。如果您检查的是一个值,而不是对它执行一个运算符,那么当表达式评估变成一个非操作时,可能会有一个理论上的性能优势。

    但在本例中,我希望JIT为两个表达式生成相同的字节码。

        6
  •  0
  •   RHicke    15 年前

    在这两个结果中生成的字节码应该没有区别,除非它是为一个资源非常有限的设备创建代码(在这种情况下,你不应该在爪哇写),否则差异是微不足道的,你应该决定写这两个代码的哪一个方法是一个更明显的解决方案。

        7
  •  0
  •   helpermethod    15 年前

    思考微观优化几乎在任何情况下都是浪费时间,并导致以错误的方式思考…

        8
  •  0
  •   Community CDub    7 年前

    我问了一个类似的问题关于C++/VS2008。

    Would VS2008 c++ compiler optimize the following if statement?

    在C++中避免V= V==TyPOS,您倾向于写

    if (NULL == ptr) { ... }
    if (false == boo) { ... }
    if (20 == num) { ... }
    

    等。

    在您习惯之前,它的可读性稍差。