Object myObject = true ? new Integer(25) : new Double(25.0);
System.out.println(myObject);
Strangely, it outputs 25.0 instead of 25
Whats going on?
The conditional operator works as follows: The first operand is implicitly converted to bool . It is evaluated and all side effects are completed before continuing. If the first operand evaluates to true (1), the second operand is evaluated.
A conditional operator is a single programming statement, while the 'if-else' statement is a programming block in which statements come under the parenthesis. A conditional operator can also be used for assigning a value to the variable, whereas the 'if-else' statement cannot be used for the assignment purpose.
There's a different emphasis: An if / else statement emphasises the branching first and what's to be done is secondary, while a ternary operator emphasises what's to be done over the selection of the values to do it with.
The conditional (ternary) operator is the only JavaScript operator that takes three operands: a condition followed by a question mark ( ? ), then an expression to execute if the condition is truthy followed by a colon ( : ), and finally the expression to execute if the condition is falsy.
Your code returns the second operand (new Integer(25)
) as you expected, but it converts it to a Double
due to the following rules.
Here's what JLS 15.25 says :
if the second and third operands have types that are convertible (§5.1.8) to numeric types, then there are several cases:
- If one of the operands is of type byte or Byte and the other is of type short or Short, then the type of the conditional expression is short.
- If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant expression (§15.28) of type int whose value is representable in type T, then the type of the conditional expression is T.
- If one of the operands is of type T, where T is Byte, Short, or Character, and the other operand is a constant expression (§15.28) of type int whose value is representable in the type U which is the result of applying unboxing conversion to T, then the type of the conditional expression is U.
- 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).
And the numeric promotion :
5.6.2. Binary Numeric Promotion
When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:
If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
If either operand is of type double, the other is converted to double.
In your example, you have an Integer
and a Double
. They are unboxed to int
and double
and then the int
is converted to a double
.
There is some wierd autoboxing stuff going on - you can see it better if you use different numbers:
Object myObject = true ? new Integer(25) : new Double(22.0);
Now, myObject will still be assigned a Double(25.0), not the 22.0 you would expect if the conditional didn't work. Basically, because Java thinks you are doing some sort of calculation involving an int and a double it returns the result of the iif as a "double" primative and then autoboxes it back to a Double().
You could also get it to behave as expected by forcing it to treat the values as type Object():
Object myObject = true ? (Object) new Integer(25) : (Object) new Double(22.0);
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