char和具有最终访问修饰符的字节 – java
请看下面的示例我无法理解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行编译成功它根本不需要任何转换所以我的问题是为什么当我使用带有byte
最终访问修饰符时, char
c表现不同
因为使用final
限定它会使变量成为常量变量,这是一个常量表达式 。 所以
final byte b = 1; char c = 2; c = b; // line 2
实际上成了
final byte b = 1; char c = 2; c = 1;
并且编译器保证值1
可以适合char
变量。
对于非常量byte
变量,没有这样的保证。 byte
是有符号的, char
是无符号的 。
您正在使用JLS-5.1.4扩展和缩小原始转换 ,
以下转换结合了扩展和缩小基元转换:
byte to char
首先,通过扩展原语转换(第5.1.2节 )将
byte
转换为int
,然后通过缩小基元转换(第5.1.3节 )将结果int
转换为char
。
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.
我想这是因为java编译器用它们的值替换了对final
变量的引用(几乎就像C中的预处理器)。 由于值1
对于char
类型是合法的,因此最后一行被转换为
c = 1;
这是成功编译的。