byte b1=1,b2=2,b3,b6;
final byte b4=4,b5=6;
b6=b4+b5; // line3
b3=b1+b2; // line4: error: incompatible types: possible lossy conversion from int to byte
System.out.println(b3+b6);
Run Code Online (Sandbox Code Playgroud)
为什么第3行是对的?似乎类型不正确,我应该得到第4行的错误.
错误发生在第4行而不是第3行,因为编译器知道final变量的值,但不知道非final变量的值.编译器看到final并且变量在使用之前已经明确赋值为常量值,并且作为变量final,该值无法更改.由于编译器知道这些值,因此它知道值10(b4+b5)的转换没有丢失.实际上,它们实际上是常量而且你正在做b6=10 - 如果你看一下如果我们删除第4行并调整第6行所生成的字节码,我们就会发现这正是编译器所做的:完全优化b4和b5完全.
如果为b4和b5(100例如)选择了不同的值,那么第3行也会出现错误:
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);
Run Code Online (Sandbox Code Playgroud)
这是展示这个的东西,将编译
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);
Run Code Online (Sandbox Code Playgroud)
这是反汇编:
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
请注意
4: bipush 10 6: istore 4
...存储字面值10 b6.