it-swarm.com.ru

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

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

short thirty = 10 * 3;

Допустимое присвоение переменной shortthirty?

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

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

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

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

100
Ceiling Gecko

Потому что компилятор заменяет 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

137
TheLostMind

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

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

Было бы иначе, если бы ten и three были отмечены final.

18
Bathsheba

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

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

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

0
Nicolas Henneaux