javadata-conversionprimitiveboxing

Integer -> double unboxes, but Double -> int doesn't unbox. Why?


To avoid confusion, I'm looking for the rule/JLS entry.

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:

  1. Integer is unboxed to int
  2. the int value undergoes a widening primitive conversion from int -> double

Integer 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:

But these aren't:


Solution

  • There's a table showing allowed conversions within §5.5:

    • signifies no conversion allowed
    • ω signifies widening primitive conversion
    • ⊗ signifies unboxing conversion

    enter image description here

    The table shows Integer -> double performs unboxing & widening conversions, but Double -> int does not perform unboxing.

    Since unboxing doesn't occur, we get a type error rather than a lossy conversion error.