To avoid confusion, I'm looking for the rule/JLS entry.
I'm not asking why Double -> int would fail, I'm asking about the way it fails
I'm aware of the lossy conversion, as I've mentioned in my question - I'm not asking about data loss between double -> int
I'm not asking for someone's "best guess" on why the developers designed it this way
I'm asking why Integer -> double performs a conversion (unbox & widening), while Double -> int performs no conversion (not even unboxing)
I'm looking for the JLS entry that mentions this Reference -> primitive conversion inconsistency, where unboxing occurs in one situation, but not the other.
This Integer -> double conversion compiles with no error
double d = Integer.valueOf(1);
It implies the following occurs:
Integer is unboxed to intint value undergoes a widening primitive conversion from int -> doubleInteger is unboxed. The unboxed value is then widened. This gives the same behavior as int -> double
The creates the assumpsion that Double -> int will also unbox, giving the same behavior as double -> int
For the code
int i = Double.valueOf(1);
I would expect the error message
lossy conversion from double to int
Assuming the Double gets unboxed, we should observe the same behavior as double -> int
Instead, we get a typing error
Cannot convert Double to int
What is the explanation behind this behavior?
Why does unboxing occur between Integer -> double, but no unboxing occurs between Double -> int?
Why are these congruent:
Integer -> doubleint -> doubleBut these aren't:
Double -> intdouble -> intDouble only has two valueOf methods: one for String input and one for double inputs.
So, while you wrote Double.valueOf(1) where that 1 is clearly an int, the method signature is valueOf(double) so (if this were to even run) your int value would get upgraded to a double and then the method runs. As such, your int i = Double.valueOf(1) is really int i = Double.valueOf(1.0) to which the Java compiler goes "a double can't be safely converted to an int, so: no".
Although of course, it doesn't even need to do that: it knows the return value for Double.valueOf is a Double, no matter what you've put in, so it sees code that tries to assign a Double to an int, knows this is impossible, and without caring about anything else, it'll go "RHS is incompatible with LHS, so: no".
Though interestingly, "The[sic] creates the assumpsion[sic] that Double -> int will also unbox" is both wrong (no value unboxing happens) and not entirely wrong (there's type "unboxing"). You're giving Java an assignment with types int = Double, Java sees incompatible types, but also knows that this is a primitive assignment and that Double can unbox to the primitive double. However, as that's still an incompatible assignment, Java nopes out with the original int/Double incompatibility error (so that you know "what's wrong with your code" rather than "what's wrong in whatever code magic the parser applied")
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