Long ll = 102; // Error
Byte bb = 101; // No error
Why Long
assignment is resulting in compile time error while Byte
assignme
long
to a Long
, an int
to an Integer
, etc.int
So, it should be clear why the assignment to Long
won't work: an int
is trying to be cast to a long
then auto boxed to a Long
in one step... no go.
However, numeric literals in the range -128
to 127
may be interpreted as byte
literals in the right context, so that's why the assignment to Byte
works.
See 5.1.7 Boxing Conversion of the JLS
- If p is a value of type int, then boxing conversion converts p into a reference r of class and type Integer, such that r.intValue() == p
Because 102
is an integer literal, it's type is int
and auto boxing will convert it to Integer
(as the spec says), but an Integer
can not be casted to Long
.
Thus when you use a long
literal or cast the int
literal to long
the JLS will use the boxing conversion and the result will be a Long
object.
This will be fine
Long long1 = (long) 102;
Long long2 = 102L;
Long long3 = 102l;
The second one
Byte bb = 101;
works, because of the 5.2. Assignment Conversion
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.
So 101
is a integer literal, but there is an assignment that needs a narrowing conversion (int -> byte) and the value of the int
is within the byte
value range. Thus it is representable as the variable type (see spec) and it is converted.
This will NOT WORK of course
Byte bb = 128; // can not be represented as the variable type. Thus no narrowing conversion.
This is happening because you are using Long
rather than long
. The Java autoboxing will not both convert from int
to long
and then autobox long
to Long
in the same step.
Change your code to long ll
and it will work.
There is no marker in java for byte
primitives - any value entered within a valid range for a byte
(-128 to +127) can be treated as either a byte
or an integer
depending on context. In this case it processes it as byte
and then autoboxing is able to work on it.
I'm not sure why the decision was made to have Java work this way. It does seem that byte handling is inconsistent from all the other number types.