char和具有最终访问修饰符的字节 - java

时间:2014-11-20 16:30:06

标签: java char byte primitive scjp

请看下面的示例我无法理解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的行为会有所不同

3 个答案:

答案 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;

编译成功。