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?
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).
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)
.