I have seen it discussed somewhere that the following code results in obj
being a Double
, but that it prints 200.0
from the left hand side.
Object obj = true ? new Integer(200) : new Double(0.0);
System.out.println(obj);
Result: 200.0
However, if you put a different object in the right hand side, e.g. BigDecimal
, the type of obj
is Integer
as it should be.
Object obj = true ? new Integer(200) : new BigDecimal(0.0);
System.out.println(obj);
Result: 200
I presume that the reason for this is something to do with casting the left hand side to a double
in the same way that it happens for integer
/double
comparisons and calculations, but here the left and right sides do not interact in this way.
Why does this happen?
You need to read section 15.25 of the Java Language Specification.
In particular:
So binary numeric promotion is applied, which starts with:
That's exactly what happens here - the parameter types are converted to
int
anddouble
respectively, the second operand (the third in the original expression) is then of typedouble
, so the overall result type isdouble
.Numeric conversion in the conditional operator ? :
In the conditional operator
a
?
b
:
c
, if bothb
andc
are different numeric types, the following conversion rules are applied at compile time to make their types equal, in order:The types are converted to their corresponding primitive ones, which is called unboxing.
If one operand were a constant
int
(notInteger
before unboxing) whose value is representable in the other type, theint
operand is converted into the other type.Otherwise the smaller type is converted into the next greater one until both operands have the same type. The conversion orders are:
byte
->short
->int
->long
->float
->double
char
->int
->long
->float
->double
Eventually the whole conditional expression gets the type of its second and third operands.
Examples:
If you combine
char
withshort
, the expression becomesint
.If you combine
Integer
withInteger
, the expression becomesInteger
.If you combine
final int i = 5
with aCharacter
, the expression becomeschar
.If you combine
short
withfloat
, the expression becomesfloat
.In the question's example, 200 is converted from
Integer
intodouble
, 0.0 is unboxed fromDouble
intodouble
and the whole conditional expression becomes becomesdouble
which is eventually boxed intoDouble
becauseobj
is of typeObject
.