Sandy,
I think your problem comes about because you don't understand what the compiler sees:
int i -> -20 (default value specified,but changeable)
int k -> i (k can never reference anything else but i)
int j -> 20 (j can never be changed from 20)
byte b -> j (from above we know this same as b -> 20 literal integer)
byte b1 -> i (byte pointing to changeable integer)
byte b2 -> k (byte pointing to integer reference pointing to changeable integer)
From the above, we can see that just because k points to i doesn't mean that the value pointed to by i (integer) can always fit into a byte. You have given a default value of -20 for i but that can be changed by any constructor. Since the compiler is dealing with changeable values it just uses
Java default rules: Narrowing of primitives is automatic but Widening must use cast!
Enjoy,
Manfred.