1

If I have Ternary syntax like this, compiler does not throw any compilation error:

int s = 2;
Double sdf = (s > 3 ?  new Double(12) : new Integer(12));

However if I have this, it is throwing compilation error:

Required type: Double Provided: Integer

Double sdf = (s > 3 ?  new Integer(12) : new Integer(12));
Gautham M
  • 4,816
  • 3
  • 15
  • 37
user3055964
  • 130
  • 2
  • 11
  • Best practice dictates that ideally both branches of the ternary expression have the same type, and both also have the same type as the LHS. As to why you are seeing this, it has to do with casting rules. But, you should not rely on them anyway. – Tim Biegeleisen Mar 21 '21 at 04:25
  • Thanks for your advice - However, I am learning Java and experimenting to understand how Java works, so I am doing negative learning. – user3055964 Mar 21 '21 at 04:36
  • hope this helps too: https://stackoverflow.com/questions/34694181/numeric-type-promotion-with-conditional-expression – Brooklyn99 Mar 21 '21 at 04:48

3 Answers3

2

This happens because if we use wrapped primitive values like in the question (Integer, Float, Double etc.) in a ternary operator, both values will be unboxed and coerced to a common type.

This may result in unexpected results as well.

In the first example, new Integer(12) would be converted to a double as it is the common type. Hence there are no compilation issue.

But in the second example both are Integer which is not compatible with the left hand side type Double.

Example taken from Sonar rule description S2154:

Integer i = 123456789;
Float f = 1.0f;
// Assume condition = true
Number n = (condition) ? i : f; // i is coerced to float. n = 1.23456792E8

To fix this, we need to do explicit casting:

Integer i = 123456789;
Float f = 1.0f;
// Assume condition = true
Number n = condition ? (Number) i : f;  // n = 123456789

Additional suggestion: Do not use new Double() or new Integer() etc. These constructors are deprecated. Instead use valueOf method

Gautham M
  • 4,816
  • 3
  • 15
  • 37
2

According to the Conditional Operator ? : specification, in case if one operand is Integer and the other is Double binary numeric promotion is used to resolve the result type.

Based on the rules, in the first example, the result type is Integer but Double in the second one (unboxing + widening).

Vitalii Vitrenko
  • 9,763
  • 4
  • 43
  • 62
1

It's because internally type is pramoted. Integer can be pramoted to double. But double can't be demoted to Integer. Pramotion happens in following way Byte -->Short-->Interger-->Long-->Float -->Double