The conversion from byte
to char
is a widening and narrowing primitive conversion, as described in paragraph 5.1.4 of the Java Language Specification.
As the JLS describes, this is done via an intermediate step; the byte
is converted to int
via a widening primitive conversion and then the int
is converted to char
via a narrowing primitive conversion (see 5.1.3).
Paragraph 5.2 explains when a cast is necessary when you do an assignment:
... 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.
Your variable b1
is indeed a constant, but your variable b2
is not, so this rule applies for b1
but not for b2
.
So: you can assign b1
to c
because b1
is a constant and the value of the constant, 1
, fits in a char
, but you cannot assign b2
to c
without a cast because b2
is not a constant.