我已经看到它在某处讨论过以下代码导致obj
成为Double
,但它从左侧打印200.0
。
Object obj = true ? new Integer(200) : new Double(0.0);
System.out.println(obj);
结果:200.0
但是,如果您在右侧放置一个不同的物体,例如BigDecimal
,obj
的类型应为Integer
。
Object obj = true ? new Integer(200) : new BigDecimal(0.0);
System.out.println(obj);
结果:200
我认为造成这种情况的原因是将左侧投射到double
的方式与integer
/ double
比较和计算的方式相同,但这里的左右两边都不会以这种方式相互作用。
为什么会这样?
答案 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。
这正是这里发生的事情 - 参数类型分别转换为int
和double
,第二个操作数(原始表达式中的第三个)的类型为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
最终,整个条件表达式获取其第二个和第三个操作数的类型。
示例:
如果您将char
与short
合并,则表达式将变为int
如果您将Integer
与Integer
合并,则表达式将变为Integer
如果您将final int i = 5
与Character
合并,则表达式将变为char
如果您将short
与float
合并,则表达式将变为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.
}