Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the result of conditional operator opposite of expected? [duplicate]

Tags:

java

operators

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?

like image 422
Snehal Masne Avatar asked Dec 24 '14 09:12

Snehal Masne


People also ask

How does a conditional operator work?

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.

What is the difference between conditional operator and if-else?

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.

Why ternary operator is better than if-else?

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.

What is the format of conditional operator?

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.


2 Answers

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.

like image 93
Eran Avatar answered Nov 02 '22 05:11

Eran


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);
like image 25
BarrySW19 Avatar answered Nov 02 '22 06:11

BarrySW19