我正在编写一个方法,其所有参数都是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;
}
有人可以解释为什么我会得到这个奇怪的结果吗?如果可以的话,我更愿意在这里使用三元运算符。
答案 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节:
如果第二个和第三个操作数表达式都是数值表达式,则条件表达式是数字条件表达式。
数值条件表达式的类型确定如下:[几个不适用于您的代码的情况]二进制数字提升(第5.6.2节)应用于操作数类型,并且条件表达式的类型是第二个和第三个操作数的提升类型。
section §15.25.2中扩大的规则说:
如果任一操作数的类型为double,则另一个操作数转换为double。
因此,您的Integer
已取消装箱,转换为double
,并装入Double
,数字条件表达式的类型为Double
。 (实际上,我不是100%肯定。可能是类型为double
,并且当double
分配给Number
时发生装箱。)