assigning int literal to Long in java

I see no clear rationale for happening this ..

public  class wrappers
{
    public static void main(String []args)
    {
        short s1=32767; // (primitive) works fine without compile error
        short s2=32768;   fails as this is  beyond short's range


        Short s3=32767; //(wrapper) works fine without compile error
        Short s4=32768; fails as this is beyond short's range

        long l1 =34   // (wrapper)works fine (with_in_range)


        Long l2 =34    // fails, without 34L (with_in_range)

    }

I know that when you assign int literal for wrapper classes, valueOf() is called;

while for Short(Wrapper) this seems to work but for Long(wrapper) above assignments in code fail.

Are there any rules governing these wrapper classes' assignments?

Jon Skeet
people
quotationmark

are there any rules governing these wrapper classes' assignments

Yes - the rules of the JLS. It specifies widening primitive conversions (5.1.2) and boxing conversions (5.1.7).

The list of boxing conversions includes:

  • From type int to type Integer
  • From type long to type Long

So you want a widening conversion followed by a boxing conversion. You're trying to do this in an assignment context (5.2) which states:

Assignment contexts allow the use of one of the following:

  • an identity conversion (§5.1.1)
  • a widening primitive conversion (§5.1.2)
  • a widening reference conversion (§5.1.5)
  • a boxing conversion (§5.1.7) optionally followed by a widening reference conversion
  • an unboxing conversion (§5.1.8) optionally followed by a widening primitive conversion.

Note that this list does not include a widening primitive conversion followed by a boxing conversion. The reverse is okay:

Integer x = 10;
long y = x; // Unboxing followed by widening primitive

On the face of it, it sounds like the rules could have been written to allow a widening primitive conversion followed by a boxing conversion, with rules such that Object x = 10; prefers boxing as Integer rather than Long... but type conversion rules are very hard to get right, with lots of subtleties. I wouldn't be surprised if it turned out there are some bizarre situations where it would cause big problems.

The reason the conversion to Short works is due to further rules in 5.2:

In addition, if the expression is a constant expression (§15.28) of type byte, short, char, or int:

  • A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.
  • A narrowing primitive conversion followed by a boxing conversion may be used if the type of the variable is:
    • Byte and the value of the constant expression is representable in the type byte.
    • Short and the value of the constant expression is representable in the type short.
    • Character and the value of the constant expression is representable in the type char.

In the case of

Short s = 32767;

there's a narrowing primitive conversion followed by a boxing conversion as described above.

people

See more on this question at Stackoverflow