Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the ternary operator unexpectedly cast integers?

I have seen it discussed somewhere that the following code results in obj being a Double, but that it prints 200.0 from the left hand side.

Object obj = true ? new Integer(200) : new Double(0.0);  System.out.println(obj); 

Result: 200.0


However, if you put a different object in the right hand side, e.g. BigDecimal, the type of obj is Integer as it should be.

Object obj = true ? new Integer(200) : new BigDecimal(0.0);  System.out.println(obj); 

Result: 200


I presume that the reason for this is something to do with casting the left hand side to a double in the same way that it happens for integer/double comparisons and calculations, but here the left and right sides do not interact in this way.

Why does this happen?

like image 620
HXCaine Avatar asked Nov 03 '11 22:11

HXCaine


People also ask

How do you handle 3 conditions in a ternary 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.

Why is the ternary operator bad?

Except in very simple cases, you should discourage the use of nested ternary operators. It makes the code harder to read because, indirectly, your eyes scan the code vertically. When you use a nested ternary operator, you have to look more carefully than when you have a conventional operator.

What is the purpose of ternary operator give example?

A ternary operator lets you assign one value to the variable if the condition is true, and another value if the condition is false. The if else block example from above could now be written as shown in the example below. var num = 4, msg = ""; msg = (num === 4) ?

Why use ternary operator instead of if else?

The conditional operator – also known as the ternary operator – is an alternative form of the if/else statement that helps you to write conditional code blocks in a more concise way. First, you need to write a conditional expression that evaluates into either true or false .


2 Answers

You need to read section 15.25 of the Java Language Specification.

In particular:

Otherwise, 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 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 Byte and the other operand is a constant expression of type int whose value is representable in type byte, then the type of the conditional expression is byte.
  • If one of the operands is of type Short and the other operand is a constant expression of type int whose value is representable in type short, then the type of the conditional expression is short.
  • If one of the operands is of type; Character and the other operand is a constant expression of type int whose value is representable in type char, then the type of the conditional expression is char.
  • 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 unboxing conversion (§5.1.8) and value set conversion (§5.1.13).

So binary numeric promotion is applied, which starts with:

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, using widening conversion (§5.1.2) to convert operands as necessary:

  • If any of the operands is of a reference type, unboxing conversion (§5.1.8) is performed. Then:
  • If either operand is of type double, the other is converted to double.

That's exactly what happens here - the parameter types are converted to int and double respectively, the second operand (the third in the original expression) is then of type double, so the overall result type is double.

like image 172
Jon Skeet Avatar answered Sep 22 '22 15:09

Jon Skeet


Numeric conversion in the conditional operator ? :

In the conditional operator a?b:c, if both b and c are different numeric types, the following conversion rules are applied at compile time to make their types equal, in order:

  • The types are converted to their corresponding primitive ones, which is called unboxing.

  • If one operand were a constant int (not Integer before unboxing) whose value is representable in the other type, the int operand is converted into the other type.

  • Otherwise the smaller type is converted into the next greater one until both operands have the same type. The conversion orders are:
    byte -> short -> int -> long -> float -> double
    char -> int -> long -> float -> double

Eventually the whole conditional expression gets the type of its second and third operands.

Examples:
If you combine char with short, the expression becomes int.
If you combine Integer with Integer, the expression becomes Integer.
If you combine final int i = 5 with a Character, the expression becomes char.
If you combine short with float, the expression becomes float.

In the question's example, 200 is converted from Integer into double, 0.0 is unboxed from Double into double and the whole conditional expression becomes becomes double which is eventually boxed into Double because obj is of type Object.

like image 20
Gerhard Avatar answered Sep 24 '22 15:09

Gerhard