我一直在审查一些编码人员一直在使用冗余三元运算符“以提高可读性”的代码。如:
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/