Reputation: 151
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));
Upvotes: 1
Views: 168
Reputation: 119
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
Upvotes: 1
Reputation: 10405
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).
Upvotes: 2
Reputation: 4935
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
Upvotes: 2