为什么条件运算符的结果与预期相反?

时间:2014-12-24 09:04:37

标签: java operators

Object myObject = true ? new Integer(25) : new Double(25.0);

System.out.println(myObject);

奇怪的是,它输出25.0而不是25

怎么回事?

3 个答案:

答案 0 :(得分:9)

您的代码会按预期返回第二个操作数(new Integer(25)),但由于以下规则,它会将其转换为Double

以下是JLS 15.25所说的内容:

  

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

     
      
  • 如果其中一个操作数是byte或Byte类型而另一个是short或Short类型,则条件表达式的类型很短。
  •   
  • 如果其中一个操作数是T类型,其中T是byte,short或char,另一个操作数是int类型的常量表达式(第15.28节),其值可以在类型T中表示,那么类型为条件表达式是T。
  •   
  • 如果其中一个操作数是T类型,其中T是Byte,Short或Character,另一个操作数是int类型的常量表达式(第15.28节),其值可以在类型U中表示,它是结果将取消装箱转换应用于T,则条件表达式的类型为U。
  •   
  • 否则,二进制数字提升(第5.6.2节)将应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型。   
    请注意,二进制数字提升执行值集转换(第5.1.13节),并可执行拆箱转换(第5.1.8节)。
  •   

数字促销:

  

5.6.2。二进制数字促销

     

当运算符将二进制数字提升应用于一对操作数时,每个操作数必须表示可转换为数字类型的值,以下规则适用:

     

如果任何操作数属于引用类型,则需要进行拆箱转换(第5.1.8节)。

     

应用扩展基元转换(第5.1.2节)来转换以下规则指定的一个或两个操作数:

     

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

在您的示例中,您有IntegerDouble。它们已取消装箱至intdouble,然后int将转换为double

答案 1 :(得分:3)

有一些奇怪的自动装箱东西正在进行 - 如果使用不同的数字,你会发现它更好:

    Object myObject = true ? new Integer(25) : new Double(22.0);

现在,myObject仍将被分配一个Double(25.0),而不是22.0,如果条件不起作用,则不会。基本上,因为Java认为你正在进行某种涉及int和double的计算,它会将iif的结果作为“double”primative返回,然后将其自动恢复为Double()。

您还可以通过强制它将值视为Object()类型来使其按预期运行:

    Object myObject = true ? (Object) new Integer(25) : (Object) new Double(22.0);

答案 2 :(得分:1)

编译后

Object myObject = true ? new Integer(25) : new Double(25.0);

将是以下内容

Object myObject = (double) new Integer(25);

因此,它会按预期返回新的整数(25),但会转换为双倍。

正如Eran所提到的,按照JLS 5.6.2

  

二进制数字提升(第5.6.2节)应用于操作数类型,和   条件表达式的类型是提升类型   第二和第三个操作数。

     
      
  1. 如果任何操作数属于引用类型,则会进行拆箱转换(第5.1.8节)。
  2.   
  3. 应用扩展基元转换(第5.1.2节)来转换由以下规则指定的一个或两个操作数:

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

    •   
    • 否则,如果任一操作数的类型为float,则转换另一个操作数   漂浮。

    •   
    • 否则,如果任一操作数的类型为long,则转换另一个操作数   很久。

    •   
    • 否则,两个操作数都将转换为int类型。

    •   
  4.