“错"在 Java 中使用 if 与三元运算符时的返回类型
在下面的类中,两个方法的返回类型与三元运算符的思想不一致:
In the following class, the return type of the two methods is inconsistent with the idea that the ternary operator:
return condition?a:b;
等价于
if(condition) {
return a;
} else{
return b;
}
第一个返回一个 Double,第二个返回一个 Long:
The first returns a Double and the second a Long:
public class IfTest {
public static Long longValue = 1l;
public static Double doubleValue = null;
public static void main(String[] args) {
System.out.println(getWithIf().getClass());// outpus Long
System.out.println(getWithQuestionMark().getClass());// outputs Double
}
public static Object getWithQuestionMark() {
return doubleValue == null ? longValue : doubleValue;
}
public static Object getWithIf() {
if (doubleValue == null) {
return longValue;
} else {
return doubleValue;
}
}
}
我可以想象这与编译器窄转换 getWithQuestionMark()
的返回类型有关,但这种语言是否明智?这肯定不是我所期望的.
I can imagine this has to do with the compiler narrow casting the return type of getWithQuestionMark()
but is that language wise ok? It's certainly not what I would have expected.
欢迎任何见解!
下面有很好的答案.此外,@sakthisundar 引用的以下问题探讨了在三元运算符中发生的类型提升的另一个副作用:Java 中棘手的三元运算符 - 自动装箱
there's very good answers below. Additionally, the following question referenced by @sakthisundar explores another side effect of the type promotion occurring in the ternary operator: Tricky ternary operator in Java - autoboxing
推荐答案
基本上是遵循JLS 的第 15.25 节,具体:
否则,如果第二个和第三个操作数具有可转换(第 5.1.8 节)为数值类型的类型,则有以下几种情况:
Otherwise, if the second and third operands have types that are convertible (§5.1.8) to numeric types, then there are several cases:
[...]
[...]
否则,二进制数值提升(第 5.6.2 节)应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型.
Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands.
所以 第 5.6 节.2 紧随其后,这基本上涉及拆箱 - 因此这使您的表达式工作就像 longValue
和 doubleValue
是 long
类型一样和double
,对long
进行加宽提升,得到double
的整体结果类型.
So section 5.6.2 is followed, which will basically involves unboxing - so this makes your expression work as if longValue
and doubleValue
were of types long
and double
respectively, and the widening promotion is applied to the long
to get an overall result type of double
.
然后将该 double
装箱,以便从该方法返回一个 Object
.
That double
is then boxed in order to return an Object
from the method.
相关文章