为什么三元运算符意外地转换整数?

HXC*_*ine 40 java casting ternary-operator conditional-operator

我已经看到它在某处讨论过以下代码导致obj成为a Double,但它200.0从左侧打印.

Object obj = true ? new Integer(200) : new Double(0.0);

System.out.println(obj);
Run Code Online (Sandbox Code Playgroud)

结果:200.0


但是,如果您在右手边放一个不同的对象,例如BigDecimal,类型objInteger理所应当的.

Object obj = true ? new Integer(200) : new BigDecimal(0.0);

System.out.println(obj);
Run Code Online (Sandbox Code Playgroud)

结果:200


我认为这样做的原因是将左侧投射到a/与比较和计算double相同的方式,但这里左右两侧不会以这种方式相互作用.integerdouble

为什么会这样?

Jon*_*eet 35

您需要阅读Java语言规范的第15.25节.

特别是:

否则,如果第二个和第三个操作数具有可转换(第5.1.8节)到数字类型的类型,则有几种情况:

  • 如果其中一个操作数的类型为字节或字节,另一个操作数的类型为short或Short,则条件表达式的类型为short.
  • 如果其中一个操作数是T类型,其中T是byte,short或char,另一个操作数是int类型的常量表达式,其值可在类型T中表示,则> - 条件表达式的类型为T.
  • 如果其中一个操作数是Byte类型而另一个操作数是int类型的常量表达式,其值可以在byte类型中表示,则条件表达式的类型是byte.
  • 如果其中一个操作数的类型为Short,另一个操作数是int类型的常量表达式,其值可在short类型中表示,则条件表达式的类型为short.
  • 如果其中一个操作数是类型的; 字符和另一个操作数是int类型的常量表达式,其值可以在char类型中表示,然后条件表达式的类型是char.
  • 否则,二进制数字提升(第5.6.2节)将应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型.请注意,二进制数字促销执行拆箱转换(第5.1.8节)和值集转换(第5.1.13节).

因此应用二进制数字促销,其开头于:

当运算符将二进制数字提升应用于一对操作数时,每个操作数必须表示可转换为数字类型的值,以下规则按顺序应用,使用扩展转换(第5.1.2节)根据需要转换操作数:

  • 如果任何操作数是引用类型,则执行拆箱转换(第5.1.8节).然后:
  • 如果任一操作数的类型为double,则另一个操作数转换为double.

这正是这里发生的事情 - 参数类型被转换为intdouble第二个操作数(原始表达式中的第三个)然后是类型double,因此整体结果类型是double.

  • @HXCaine:是的.编译器决定类型是什么,然后考虑它是否可以转换为赋值的目标.请注意,泛型类型推断是一个反例,但它是我唯一可以想到的一个:) (3认同)
  • Gah Jon Skeet打败了我:) +1 (2认同)