Please consider we have code below:
Object obj = true ? new Integer(0) : new Long(1);
System.out.println(obj.getClass() + "\nvalue = " + obj);
And its result is:
class java.lang.Long
value = 0
Instead of:
class java.lang.Integer
value = 0
Could someone clarify why we have such functionality in Java? It is very strange for me. Do you have any example where this can be useful?
UPDATE: Here is piece of bytecode, where we can see, whats going on there
NEW java/lang/Integer
DUP
LDC "0"
INVOKESPECIAL java/lang/Integer.<init> (Ljava/lang/String;)V
INVOKEVIRTUAL java/lang/Integer.intValue ()I
I2L
INVOKESTATIC java/lang/Long.valueOf (J)Ljava/lang/Long;
ASTORE 1
What's going on here is the result of
Integer
and Long
types into long
for use as the common type to apply to the conditional operator expressionThe conditional operator's second and third operands must end up having the same type, which is the resulting type of the expression. Integer
and Long
are not, of course, the same type.
However, as described in JLS§15.25, the compiler will apply binary numeric promotion when determining the possible common type to apply to the expression. That section has the handy Table 15.25-D which tells us that when the second operand is of type Integer
and the third operand is of type Long
, the compiler will do binary numeric promotion on Integer,Long
. Binary numeric promotion on Integer,Long
yields long
. So the result of the conditional operator expression is long
.
Since the expression's result type is long
, the Integer
or Long
will have to be unboxed (and then cast, in the case of Integer
).
Finally, you assign it to an Object
, which forces boxing, and wraps the long
in a Long
. Thus, you end up with a Long
containing the value 0
, which matches your output.
So effectively, if we ignore the fact the compiler will optimize half of the following away since it's dealing with a constant expression thanks to the true
in the code (I've used flag
below instead), that code ends up being this:
Object obj = Long.valueOf(flag ? (long)(new Integer(0)).intValue() : (new Long(1)).longValue());
System.out.println(obj.getClass() + "\nvalue = " + obj);
(long)(new Integer(0)).intValue()
represents unboxing the Integer
and casting it to long
so it matches the expression result type.(new Long(1)).longValue()
represents unboxing the Long
so it matches the expresion result type.Long.valueOf
represents the boxing at the end.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With