Can someone please explain why the following compiles:
final short s1 = 1; final char c1 = 1; byte b1 = s1; byte b2 = c1;
But the following doesn't (the compiler error message is Type mismatch: cannot convert from short to byte
):
short s1 = 1; char c1 = 1; byte b1 = s1; byte b2 = c1;
The answer is in the JLS - 5.2. Assignment Conversion:
.. if the expression is a constant expression (§15.28) of type
byte
,short
,char
, orint
:
- 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.
When you write:
final short s1 = 1;
The value of the expression is known at compile time, and since it cannot be changed you don't need to cast.
In your second snippet, the value is not known at compile time - it's evaluated in runtime, so you'll need an explicit cast.
If you try to compile the following code:
final byte b1 = 200; final byte b2 = 200; byte sum = b1 + b1;
You'll get a compilation error since the values at the right side are known to the compiler and it knows that the sum cannot fit into a byte
.
In the first sample, the compiler knows that s1
and c1
will never change, and that their final value (1
) fits into byte
.
In the second, the compiler worries what would happen if s1
and c1
were outside 0..255
-128..127
when they were assigned to a byte
variable, and warns you that it is unsafe.
If you explicitly cast them as balalaika suggests in comments, the compiler is relieved that you seem to know what you're doing (or at least, that it has someone to blame if things go south), and lets you do it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With