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.