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?
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 typeInteger
- From type
long
to typeLong
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
, orchar
, 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 typebyte
.Short
and the value of the constant expression is representable in the typeshort
.Character
and the value of the constant expression is representable in the typechar
.
In the case of
Short s = 32767;
there's a narrowing primitive conversion followed by a boxing conversion as described above.
See more on this question at Stackoverflow