简体   繁体   中英

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!

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.

The types of the two possible values for the conditional operator ?: should be the same. There is a little room for the values to be different, if the type of one value can be converted to the other. In this case, even when you explicitly cast value to int , the other value is a double , so binary numeric promotion occurs, and the int is re-promoted to double . That's why 2.0 is printed.

Section 15.25 of the JLS covers the ?: operator, and Section 15.25.2 covers numeric values for this operator.

The type of a numeric conditional expression is determined as follows:

  • If the second and third operands have the same type, then that is the type of the conditional expression.

  • If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.

  • 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 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.

(emphasis mine)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM