Numeric Type Promotion with Conditional Expression

2020-03-26 06:46发布

I was toying around with java, and I noticed something. It can be best shown here:

boolean boo = true;

Object object1 = boo ? new Integer(1) : new Double(2.0);

Object object2;
if (boo)
    object2 = new Integer(1);
else
    object2 = new Double(2.0);

System.out.println(object1);
System.out.println(object2);

I would expect the two to be the same, but this is what gets printed:

1.0
1

Does anyone have a good explanation for this?

2条回答
疯言疯语
2楼-- · 2020-03-26 07:27

A ternary must return the same type for both conditions, so your first result (Integer) is promoted to a double to match 2.0. See also,

Object object1 = boo ? new Integer(1) : new Double(2.0);
System.out.println(object1.getClass().getName());

This is documented at JLS-15.25.2 - Numeric Conditional Expressions which reads (in part)

Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands.

Note that binary numeric promotion performs value set conversion (§5.1.13) and may perform unboxing conversion (§5.1.8).

查看更多
贼婆χ
3楼-- · 2020-03-26 07:29

JLS section 15.25 has a table that summarizes the type of the conditional expression based on the type of its operands. For the case of Integer and Double, the table says that the type will be the result of applying binary numeric promotion to the arguments (§15.25.2)

Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands.

Note that binary numeric promotion performs value set conversion (§5.1.13) and may perform unboxing conversion (§5.1.8).

Quoting binary numeric promotion:

If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
...
If either operand is of type double, the other is converted to double.


This is what's happening for

Object object1 = boo ? new Integer(1) : new Double(2.0);
  • The reference type new Integer(1) is unboxed to the primitive int 1.
  • The reference type new Double(2.0) is unboxed to the primitive double 2.0.
  • Binary numeric promotion is performed and the result is of type double. In this case, since boo is true, the primitive int 1 will be promoted to double as 1.0.
  • Since you are storing the result in an Object, the primitive result is boxed into its wrapper type.

For the case of

Object object2;
if (boo)
    object2 = new Integer(1);
else
    object2 = new Double(2.0);

the if/else construct does not perform numeric promotion. In fact there won't be any boxing conversion. Since boo is true, the if part will be executed and object2 will have the value new Integer(1).

查看更多
登录 后发表回答