Java: Conditional Operator differs from if/else

why does the conditional operator return 2.0 and the if/else block returns 2 in the following example? I am kind of confused because these two blocks should be equal:

IF/ELSE:

double value = 2.0;
Object result;

if (value == Math.floor(value)) {
    result = ((int) value);
} else {
    result = value;
}

CONDITIONAL OPERATOR:

double value = 2.0;
Object result;
result = value == Math.floor(value) ? ((int) value) : value;

However, the command

System.out.println(result);

prints either 2.0 or 2

Thanks for your help!

Jon Skeet
people
quotationmark

The same branch is being taken in both cases. You can verify that by using very different answers for the different branches:

if (value == Math.floor(value)) {
    result = ((int) value * 100);
} else {
    result = value;
}

and

result = value == Math.floor(value) ? ((int) value * 100) : value;

In both cases, you'll get 200 or 200.0.

Another option to validate that would just be to remove the conditionality by making it constant:

boolean condition = true;
if (condition) { 
    ...
}

and

result = condition ? ...;

However, the difference is that with the conditional operator, the type of the conditional expression is double - the type of the second operand is int (due to the cast), and the type of the third operand is double. The conditional operator can only have one type, so it follows the rules in the JLS and picks double (as int is implicitly convertible to double but not vice versa). That double is then boxed as part of the assignment to result (which is of type Object). So the value of result ends up being a reference to a Double, and printed out as 2.0.

With the first approach, the result is an Integer instead, because you're assigning the int directly to result, and it's just getting autoboxed.

You can make the conditional operator behave the same way by casting either operand to Object. For example:

result = value == Math.floor(value) ? ((int) value) : (Object) value;

Now the type of the conditional operator itself is Object, the int is boxed to Integer as part of evaluating the conditional operator.

people

See more on this question at Stackoverflow