Because in the right side of
byte i = 4 * 5;
there is a constat expression, evaluated at 'compile time' and so is is know in advance it fits in a byte.
On the other hand, on the right side of
byte r = i * 5.
there is a variable, so it cannot be avaluated at 'compile time', automatic type promotion happens (see
Automatic Type Promotion in Expressions[
^]) and you need a cast.