Java 8:结合了instanceof和三元运算符的奇怪结果

时间:2014-10-22 21:17:19

标签: java ternary-operator instanceof

我正在编写一个方法,其所有参数都是double s或int s。由于两个重载的内部代码都相同,我认为编写接口以接受Number会更容易。

我需要在此方法中做的一件事是验证其中一个参数大于零。为了使它能够compare()传递的值为零,我有以下静态字段:

private static final Double ZERO_D = Double.valueOf(0);
private static final Integer ZERO_I = Integer.valueOf(0);

在相关方法中,我尝试执行此测试:

Number zero = ((stepSize instanceof Double) ? ZERO_D : ZERO_I);

奇怪的是,此代码始终将zero设置为ZERO_D

我目前正在使用以下代码成功解决此问题:

Number zero;
if (stepSize instanceof Double) {
  zero = ZERO_D;
} else {
  zero = ZERO_I;
}

有人可以解释为什么我会得到这个奇怪的结果吗?如果可以的话,我更愿意在这里使用三元运算符。

2 个答案:

答案 0 :(得分:5)

这是因为三元运算符总是求值为单一类型,在您的情况下,Java数字给出了第二个和第三个参数the final type should be Double,因此它将整数转换为匹配。

您可以强制转换为Number而不是

Number zero = ((stepSize instanceof Double) ? (Number) ZERO_D : ZERO_I);

答案 1 :(得分:0)

三元运算符的两个分支必须具有相同的类型。根据{{​​3}}的第15.25节:

  

如果第二个和第三个操作数表达式都是数值表达式,则条件表达式是数字条件表达式。

Java Language Specification说:

  

数值条件表达式的类型确定如下:[几个不适用于您的代码的情况]二进制数字提升(第5.6.2节)应用于操作数类型,并且条件表达式的类型是第二个和第三个操作数的提升类型。

section §15.25.2中扩大的规则说:

  

如果任一操作数的类型为double,则另一个操作数转换为double。

因此,您的Integer已取消装箱,转换为double,并装入Double,数字条件表达式的类型为Double。 (实际上,我不是100%肯定。可能是类型为double,并且当double分配给Number时发生装箱。)