如果我有这样的三元语法,编译器不会抛出任何编译错误:
int s = 2;
Double sdf = (s > 3 ? new Double(12) : new Integer(12));
然而,如果我有这个,它抛出编译错误:
必需类型:双重提供:整数
Double sdf = (s > 3 ? new Integer(12) : new Integer(12));
之所以会发生这种情况,是因为如果我们在三元运算符中使用问题中的包装基元值(Integer
、Float
、Double
等(,则这两个值都将被取消装箱并强制为通用类型。
这也可能导致意想不到的结果。
在第一个示例中,new Integer(12)
将被转换为double
,因为它是常见类型。因此不存在汇编问题。
但在第二示例中,两者都是与左手侧类型Double
不兼容的Integer
。
示例取自声纳规则描述S2154
:
Integer i = 123456789;
Float f = 1.0f;
// Assume condition = true
Number n = (condition) ? i : f; // i is coerced to float. n = 1.23456792E8
为了解决这个问题,我们需要进行显式铸造:
Integer i = 123456789;
Float f = 1.0f;
// Assume condition = true
Number n = condition ? (Number) i : f; // n = 123456789
附加建议:不要使用new Double()
或new Integer()
等。这些构造函数已被弃用。相反,使用valueOf
方法
根据条件运算符?:如果一个操作数是Integer
而另一个是Double
,则使用二进制数字提升来解析结果类型。
根据规则,在第一个示例中,结果类型为Integer
,但在第二个示例中为Double
(拆箱+加宽(。
这是因为内部类型是pramoted的。整数可以调整为两倍。但是double不能降级为Integer。Pramotion的发生方式如下字节-->短->Interger-->长->浮动-->双