请看下面的示例我无法理解char和byte
之间的关系byte b = 1;
char c = 2;
c = b; // line 1
给我编译错误,因为c是char
的类型,b是byte
的类型,因此必须在这种情况下进行投射
但现在这里的推文是我在代码
下面运行的时候final byte b = 1;
char c = 2;
c = b; // line 2
第2行成功编译它根本不需要任何投射
所以我的问题是,当我使用char
byte
c的行为会有所不同
答案 0 :(得分:11)
因为使用final
对其进行限定会使变量成为常量变量,即constant expression。所以
final byte b = 1;
char c = 2;
c = b; // line 2
实际上变成了
final byte b = 1;
char c = 2;
c = 1;
编译器保证值1
可以放在char
变量中。
使用非常量byte
变量,没有这样的保证。 byte
is signed, char
is unsigned。
答案 1 :(得分:2)
您正在遇到JLS-5.1.4 Widening and Narrowing Primitive Conversion,
以下转换结合了扩展和缩小基元转换:
byte to char
首先,
byte
通过扩展原始转换(§5.1.2)转换为int
,然后生成的int
转换为char
通过缩小原始转换(§5.1.3)。
final byte b = 1;
char c = (char) ((int) 2); // <-- 2 is an int literal
c = (char) ((int) 1); // <-- b is 1 a byte literal
如果用javap -v
检查字节码,你会看到值1在编译后已经替换了变量b
。
public static void main(java.lang.String[]) throws java.lang.Exception; descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Exceptions: throws java.lang.Exception Code: stack=2, locals=3, args_size=1 0: iconst_1 1: istore_1 // b = 1 2: iconst_2 3: istore_2 // c = 2 4: iconst_1 // integer1. 5: istore_2 // c = 1.
答案 2 :(得分:1)
我想这是因为java编译器将final
变量的引用替换为它们的值(几乎与C中的预处理器一样)。由于值1
对于类型char
是合法的,因此最后一行转换为
c = 1;
编译成功。