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

时间:2011-11-03 22:17:14

标签: java casting ternary-operator conditional-operator

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

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

System.out.println(obj);

结果:200.0


但是,如果您在右侧放置一个不同的物体,例如BigDecimalobj的类型应为Integer

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

System.out.println(obj);

结果:200


我认为造成这种情况的原因是将左侧投射到double的方式与integer / double比较和计算的方式相同,但这里的左右两边都不会以这种方式相互作用。

为什么会这样?

3 个答案:

答案 0 :(得分:34)

您需要阅读section 15.25 of the Java Language Specification

特别是:

  

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

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

因此应用了binary numeric promotion,它以:

开头
  

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

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

这正是这里发生的事情 - 参数类型分别转换为intdouble,第二个操作数(原始表达式中的第三个)的类型为double,所以整体结果类型为double

答案 1 :(得分:3)

条件运算符中的数字转换? :

在条件运算符 a ? b : c < / em>,如果 b c 都是不同的数字类型,则会应用以下转换规则: 编译时间,使其类型相等,按顺序:

  • 将类型转换为相应的原语,称为拆箱

  • 如果一个操作数是常量 int(取消装箱前不是Integer),其值可以在另一种类型中表示,int操作数转换为另一种类型。

  • 否则较小的类型将转换为下一个更大的类型,直到两个操作数具有相同的类型。转换订单是:
    byte - &gt; short - &gt; int - &gt; long - &gt; float - &gt; double
    char - &gt; int - &gt; long - &gt; float - &gt; double

最终,整个条件表达式获取其第二个和第三个操作数的类型。

示例:
如果您将charshort合并,则表达式将变为int 如果您将IntegerInteger合并,则表达式将变为Integer 如果您将final int i = 5Character合并,则表达式将变为char 如果您将shortfloat合并,则表达式将变为float

在问题的示例中,200从Integer转换为double,0.0从Double取消装箱到double,整个条件表达式变为最终将double装入Double,因为obj的类型为Object

答案 2 :(得分:0)

示例:

public static void main(String[] args) {
    int i = 10;
    int i2 = 10;
    long l = 100;
    byte b = 10;
    char c = 'A';
    Long result;
    // combine int with int result is int compiler error
   // result = true ? i : i2; // combine int with int, the expression becomes int
    //result = true ? b : c; // combine byte with char, the expression becomes int

    //combine int with long result will be long
    result = true ? l : i; // success - > combine long with int, the expression becomes long
    result = true ? i : l; // success - > combine int with long, the expression becomes long
    result = true ? b : l; // success - >  combine byte with long, the expression becomes long
    result = true ? c : l; // success - >  char long with long, the expression becomes long

    Integer intResult;
    intResult = true ? b : c; // combine char with byte, the expression becomes int.
   // intResult = true ? l : c; // fail combine long with char, the expression becomes long.

}