(note: Double is just an example)
When initializing a Double it needs a Double or double as value:
Double a = 0; //does not compile
unless you cast to double, or append 'd'
Double b = (double)0; //compiles
Double c = 0d; //compiles
When it becomes confusing is...
This compiles, although its value becomes 0 (int)
Double d = true ? 0 : 0d; //compiles, but always 0 (eclipse 'complains' on 0d calling it *Dead code*. So it knows it will return 0
As does this
Double e = false ? 0 : 0d; //compiles, always 0d
But these do not compile:
Double f = false ? 0 : 0; //cannot convert from int to Double
Double g = true ? 0 : 0; //cannot convert from int to Double
Why is it given an error for f and g but not for d
ps. Using Java8 (expect not a difference, but upgrades happen)
It compiles because according to Java specs (at §15.25), if operands have different types and they're convertible to numeric types then binary numeric promotion applies (at §5.6.2):
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.
It doesn't matter if double is first or second operand, result will be a double.
Going back to your examples:
Double e = false ? 0 : 0d;
Double a = true ? 0 : 0d;
They're all converted to double because of numeric promotion however this:
Double f = false ? 0 : 0;
It will fail because result of condition ? 0 : 0
is always an integer, from §15.25 we know that:
If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression.
And assignment is invalid. Note that this exact case is used in specs to illustrate numeric promotion applied to ternary operators at §5.6.2-1:
class Test {
public static void main(String[] args) {
int i = 0;
float f = 1.0f;
// Omitted code...
// Here int:float is promoted to float:float:
f = (b==0) ? i : 4.0f;
System.out.println(1.0/f);
}
}
Finally note that your required final type (the one ternary operator expression will be used vs) doesn't play in this game and this code doesn't compile:
int n = true ? 0 : 0d; // Cannot assign a double to an int
The ternary operator needs both values to be of a single type. Since you have an int and a double and there is a conversion possible from int to double without loss of precision*, they will both be converted.
Therefore if you do
Double d = true ? 1 : 2.0;
It is actually compiled as
Double d = true ? (double)1 : 2.0;
Therefore there will be no problems with the code. If both values are int, then the common type is int and no implicit conversion is made.
* with long and double or int and float there might not be possibility to convert without loss of precision since there aren't enough bits in the mantissa to represent all integer values exactly
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With