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 isbyte,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.