Object myObject = true ? new Integer(25) : new Double(25.0);
System.out.println(myObject);
奇怪的是,它输出25.0而不是25
怎么回事?
答案 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 。
在您的示例中,您有Integer
和Double
。它们已取消装箱至int
和double
,然后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节)应用于操作数类型,和 条件表达式的类型是提升类型 第二和第三个操作数。
- 如果任何操作数属于引用类型,则会进行拆箱转换(第5.1.8节)。
- 醇>
应用扩展基元转换(第5.1.2节)来转换由以下规则指定的一个或两个操作数:
如果任一操作数的类型为double,则另一个操作数转换为double 。
否则,如果任一操作数的类型为float,则转换另一个操作数 漂浮。
否则,如果任一操作数的类型为long,则转换另一个操作数 很久。
否则,两个操作数都将转换为int类型。