Почему "короткая тридцать = 3 * 10" является правовым заданием?

Если short автоматически повышается до int в арифметических операциях, то почему:

short thirty = 10 * 3;

Юридическое назначение на short переменная thirty?

В свою очередь это:

short ten = 10;
short three = 3;
short thirty = ten * three; // DOES NOT COMPILE AS EXPECTED

так же как и это:

int ten = 10;
int three = 3;
short thirty = ten * three; // DOES NOT COMPILE AS EXPECTED

не компилируется, потому что назначение int значение для short не допускается без кастинга, как ожидалось.

Что-то особенное происходит с числовыми литералами?

3 ответа

Решение

Потому что компилятор заменяет 10*3 с 30 на самом времени компиляции. Итак, эффективно: short thirty = 10 * 3 рассчитывается во время компиляции.

Попробуйте изменить ten а также three в final short (заставляя их компилировать постоянные времени) и посмотрим, что произойдет:P

Изучите байт-код, используя javap -v для обеих версий (10*3 а также final short). Вы сможете увидеть, что есть небольшая разница.

Итак, вот разница в байтовом коде для разных случаев.

Случай 1:

Java-код: main() { short s = 10*3; }

Байт-код:

stack=1, locals=2, args_size=1
         0: bipush        30  // directly push 30 into "s"
         2: istore_1      
         3: return   

Дело -2:

public static void main(String arf[])  {
   final short s1= 10;
   final short s2 = 3;
   short s = s1*s2;
}

Байт-код:

  stack=1, locals=4, args_size=1
         0: bipush        10
         2: istore_1      
         3: iconst_3      
         4: istore_2      
         5: bipush        30 // AGAIN, push 30 directly into "s"
         7: istore_3      
         8: return   

Дело -3:

public static void main(String arf[]) throws Exception {
     short s1= 10;
     short s2 = 3;
     int s = s1*s2;
}

Байт-код:

stack=2, locals=4, args_size=1
         0: bipush        10  // push constant 10
         2: istore_1      
         3: iconst_3        // use constant 3 
         4: istore_2      
         5: iload_1       
         6: iload_2       
         7: imul          
         8: istore_3      
         9: return 

В приведенном выше случае 10 а также 3 взяты из локальных переменных s1 а также s2

Да, что-то особенное происходит с буквальным падежом: 10 * 3 будет оцениваться во время компиляции. Так что вам не нужно явное (short) преобразование для умноженных литералов.

ten * three не оценивается во время компиляции, поэтому требует явного преобразования.

Было бы другое дело, если бы ten а также three были отмечены final,

Следующий ответ добавляет раздел JLS и некоторые подробности об этом поведении.

Согласно JLS §15.2 - Формы выражений

Некоторые выражения имеют значение, которое может быть определено во время компиляции. Это постоянные выражения (§15.28).

Другие вопросы по тегам