Search code examples
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 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:

  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:

  • Integer -> double
  • int -> double

But these aren't:

  • Double -> int
  • double -> int

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.