2014-11-20 4 views
5

Пожалуйста, обратите внимание на примере ниже я не могу понять отношение между полукоксом и байтомсимвола и байты с окончательным модификатором доступа - Java

byte b = 1; 
char c = 2; 

c = b; // line 1 

Дай мне ошибку компиляции, потому что с является типом char и Ь типа byte так литье является обязательным в таком состоянии

но теперь tweest здесь, когда я запускаю ниже код

final byte b = 1; 
char c = 2; 

c = b; // line 2 

л ине 2 успешно компилировать не нужно никакого литья вообще поэтому мой вопрос почему char Ĉ ведут себя иначе, когда я использую окончательный модификатор доступа с byte

ответ

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.

+0

благодарит gotach точки :) –

1

Я предполагаю, что это происходит потому, что java-компилятор заменяет ссылки на переменные final по их значениям (почти как у процессора до C). Поскольку значение 1 является законным для типа char последняя строка преобразуется в

c = 1; 

, который компилируется успешно.

+0

'final' переменные с постоянными выражениями. то есть'byte a = 1; final b = a; char c = b; 'все еще не удается. – weston

2

Вы работаете в JLS-5.1.4 Widening and Narrowing Primitive Conversion,

Следующая преобразование сочетает уширение и сужающие примитивные преобразования:

  • byte to char

Во-первых, byte конвертируется в int через расширение примитивного преобразования (§5.1.2), а затем результат ting 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 

Если изучить bytescodes с 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.