Java三元与大对象相比

Joa*_*eiß 3 java

三元运算符通常只是一个哲学讨论的主题:是否

a=b>5?1:0;
Run Code Online (Sandbox Code Playgroud)

更可读,更快,更酷

if(b>5) { a=1; } else {a=0;}
Run Code Online (Sandbox Code Playgroud)

(带或不带花括号)我通常不在乎.我喜欢我的三元运算符.但我们讨论了这段代码:

BigObject myBigObject=null;
...
do {
   myBigObject=
     myBigObject==null?
     createBigObject():
     myBigObject;
...
} while(manyIteration);
Run Code Online (Sandbox Code Playgroud)

同事声称这个构造将创建myBigObject将被复制每个循环(除了第一个),这将浪费宝贵的时间和内存,并且他发现了三元运算符无用的情况.唯一的方法是:

do {
     if(myBigObject==null)
       myBigObject=createBigObject();
...
} while(manyIteration);
Run Code Online (Sandbox Code Playgroud)

我认为聪明的编译器会看到对象被分配给自己并将其优化出来.

但谁是对的?

Tun*_*aki 5

明确的答案在于JLS 第15.25节(强调我的):

然后使用得到的布尔值来选择第二个或第三个操作数表达式: - 如果第一个操作数的值是true,则选择第二个操作数表达式.- 如果第一个操作数的值为false,则选择第三个操作数表达式.

然后评估所选择的操作数表达式,并将结果值转换为由下述规则确定的条件表达式的类型.

此转换可能包括装箱或拆箱转换(§5.1.7,§5.1.8).

未针对条件表达式的特定评估评估未选择的操作数表达式.

这意味着并不总是评估两个表达式:只需要那个表达式.实际上,你们谁都是对的.

  • 你错了,因为编译器并不聪明:它是由语言本身指定的;
  • 你的同事是错的,因为如果不需要,表达式将不会被评估.

在代码中

myBigObject = myBigObject == null ? createBigObject() : myBigObject;
              ^-----------------^   ^---------------^             
           this is true the 1st time, hence that ^ is evaluated


myBigObject = myBigObject == null ?    createBigObject()     :        myBigObject;
              ^-----------------^                              
           this is false the 2nd time, hence that ^ is NOT evaluated, that ^ is
Run Code Online (Sandbox Code Playgroud)

请注意,执行的只是分配myBigObject给自身,而不是创建新对象.