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);
为什么第3行是对的?看起来类型不正确,我应该得到第4行的错误。
答案 0 :(得分:8)
错误发生在第4行而不是第3行,因为编译器知道final
变量的值,但不知道非final
的值变量。编译器看到final
并且变量在使用前明确赋值为常量值,并且变量为final
时,该值无法更改。由于编译器知道值,因此它知道值10(b4+b5
)的转换没有损失。事实上,它们是有效常量而你正在做b6=10
- 如果你看一下如果我们删除第4行并调整第6行所生成的字节码,我们就会发现这正是编译器的作用:优化{{完全离开1}}和b4
。
如果您为b5
和b4
(例如b5
)选择了不同的值,那么您在第3行也会收到错误:
100
这是展示这一点的东西,将编译
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);
这是反汇编:
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存储在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);
。
答案 1 :(得分:-1)
JVM如何处理关键字“final”? 运行时的JVM不知道这个修饰符。 Compilator确实。
你的问题不是最终的,要消除错误,请执行以下操作:
b3=(byte)(b1+b2); // line isn't invalid now
前面定义的最终变量的一次赋值是一个有效的陈述本身。
第3行 - 编译器只是将您的值内联为整数常量。
L4
LINENUMBER 30 L4
BIPUSH 10
ISTORE 4
第4行 - 编译器不能这样做。
L5
LINENUMBER 31 L5
ILOAD 1
ILOAD 2
IADD
I2B
ISTORE 3