The error occurs on line 4 and not line 3 because the compiler knows the values of the final
variables, but doesn't know the values of the non-final
variables. The compiler sees final
and that the variable is definitely assigned prior to use with a constant value, and as the variable is final
, that value cannot be changed. Since the compiler knows the values, it knows that there is no loss in the conversion of the value 10 (b4+b5
). In fact, they're effectively constants and you're doing b6=10
— and if you look at the bytecode generated if we remove line 4 and adjust line 6, we see that that's exactly what the compiler does: Optimizes b4
and b5
away entirely.
If you chose different values for b4
and b5
(100
, for instance), you'd get an error on line 3 as well:
byte b1=1,b2=2,b3,b6;
final byte b4=100,b5=100;
b6=b4+b5; // line3 error: incompatible types: possible lossy conversion from int to byte
b3=b1+b2; // line4 error: incompatible types: possible lossy conversion from int to byte
System.out.println(b3+b6);
Live on ideone
Here's something demonstrating this, that will compile
byte b1=1,b2=2,b3,b6;
final byte b4=4,b5=6;
b6=b4+b5; // line3
//b3=b1+b2; // line4
//System.out.println(b3+b6);
System.out.println(b6);
And here's the disassembly:
public static void main(java.lang.String[]) throws java.lang.Exception;
Code:
0: iconst_1
1: istore_1
2: iconst_2
3: istore_2
4: bipush 10
6: istore 4
8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
11: iload 4
13: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
16: return
Note the
4: bipush 10
6: istore 4
...which is storing the literal value 10 in b6
.