java - Java 编译器是否优化了不必要的三元运算符?

标签 java compiler-optimization code-readability

我一直在审查一些编码人员一直在使用冗余三元运算符“以提高可读性”的代码。如:

boolean val = (foo == bar && foo1 != bar) ? true : false;

显然,最好将语句的结果分配给 boolean 变量,但编译器是否关心?

最佳答案

我发现不必要地使用三元运算符会使代码更加困惑和可读性差,这与初衷相反。

话虽如此,编译器在这方面的行为可以很容易地通过比较 JVM 编译的字节码来测试。
这里有两个模拟类来说明这一点:

案例一(没有三元运算符):

class Class {

    public static void foo(int a, int b, int c) {
        boolean val = (a == c && b != c);
        System.out.println(val);
    }

    public static void main(String[] args) {
       foo(1,2,3);
    }
}

案例二(使用三元运算符):

class Class {

    public static void foo(int a, int b, int c) {
        boolean val = (a == c && b != c) ? true : false;
        System.out.println(val);
    }

    public static void main(String[] args) {
       foo(1,2,3);
    }
}

案例一中 foo() 方法的字节码:

       0: iload_0
       1: iload_2
       2: if_icmpne     14
       5: iload_1
       6: iload_2
       7: if_icmpeq     14
      10: iconst_1
      11: goto          15
      14: iconst_0
      15: istore_3
      16: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      19: iload_3
      20: invokevirtual #3                  // Method java/io/PrintStream.println:(Z)V
      23: return

案例二中 foo() 方法的字节码:

       0: iload_0
       1: iload_2
       2: if_icmpne     14
       5: iload_1
       6: iload_2
       7: if_icmpeq     14
      10: iconst_1
      11: goto          15
      14: iconst_0
      15: istore_3
      16: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      19: iload_3
      20: invokevirtual #3                  // Method java/io/PrintStream.println:(Z)V
      23: return

请注意,在这两种情况下,字节码是相同的,即编译器在编译 val boolean 值时会忽略三元运算符。


编辑:

关于这个问题的讨论已经走向了几个方向之一。
如上所示,在这两种情况下(有或没有冗余三元)编译的 java 字节码是相同的
这是否可以被Java 编译器视为一种优化,这在一定程度上取决于您对优化的定义。在某些方面,正如在其他答案中多次指出的那样,有理由认为不 - 这不是一种优化,因为在这两种情况下,生成的字节码都是执行的最简单的堆栈操作集这个任务,不管三元。

但是关于主要问题:

Obviously it would be better to just assign the statement’s result to the boolean variable, but does the compiler care?

简单的答案是否定的。编译器不在乎。

关于java - Java 编译器是否优化了不必要的三元运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54495939/

相关文章:

java - 处理程序和 Viewparts 中的 ClassNotFoundException eclipse rcp e4

java - HOCON替换默认值

c++ - 链接时间优化与。项目内联;每种方法的局限性

java - 无法通过 eBay 的库存 API 列出商品

java - 如何在java中使用StrSubstitutor进行嵌套Map

c# - 为什么 .NET JIT 编译器决定不内联或优化对没有副作用的空静态方法的调用?

c - `pointer[restrict static 1]` 在声明这样的指针时会带来什么优化好处?

c++ - 返回与不返回函数?

node.js - 检查 Node 中的错误参数

java - 使用 SAX 解析器解析大型 XML 文件时,该类变得臃肿且不可读 - 如何解决这个问题?