Подтвердить что ты не робот

Java + Operator

Я не могу понять идею оператора сложения или типа данных short.

Он сказал, что:

short a = 1;
short b = 2;
short c = a + b;

который не будет компилироваться, потому что оператор добавления всегда отличает short, chart, byte типы данных до int, и я это понимаю. Но это:

short c = 1 + 2;

работает отлично. Итак, если оператор сложения автоматически преобразует short в int, а затем применит результат (где результат thecourse будет int), почему это работает нормально?

Изменить: Этот вопрос не дублируется Примитивный тип 'short' - литье в Java, так как я понимаю процесс конверсий. Кроме того, в этом вопросе речь идет о преобразованиях типов данных, когда мой вопрос относится к литералам int.

4b9b3361

Ответ 1

1 + 2 - это постоянное выражение, а a + b - нет.
Это важно для оценки их.
Первый будет выполнен во время компиляции, второй - во время выполнения.

JLS 8 утверждает:

15.28. Константные выражения

Постоянное выражение представляет собой выражение, обозначающее значение примитивного типа или Строка, которая не завершается внезапно и составлена ​​с использованием только следующее:

  • Литералы примитивного типа и литералов типа String (§3.10.1, §3.10.2, §3.10.3, §3.10.4, §3.10.5)

  • Передает примитивные типы и приведения типов String (§15.16)

  • Унарные операторы +, -, ~, и! (но не ++ или -) (§15.15.3, §15.15.4, §15.15.5, §15.15.6)

  • Мультипликативные операторы *,/и% (§15.17)

  • Аддитивные операторы + и - (§15.18)

........................

Здесь:

short c = 1 + 2;

1 + 2 состоит из двух int литералов и одного аддитивного оператора.
Таким образом, это считается постоянным выражением. Константные выражения оцениваются во время компиляции.
Итак, short c оценивается как 3

Вот пример класса:

package stackoverflow;

public class EvaluationClass {

    public void foo(){
       short c = 1 + 2;
    }
}

Вот разобранный код:

Compiled from "EvaluationClass.java"
public class stackoverflow.EvaluationClass {
  public stackoverflow.EvaluationClass();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()
       4: return

  public void foo();
    Code:
       0: iconst_3
       1: istore_1
       2: return
}

Мы можем увидеть инструкцию 0: iconst_3, которая загружает 3 int в стек.


Если здесь:

short a = 1;
short b = 2;
short c = a + b;

a + b оценивается только во время выполнения, поскольку a и b не являются постоянными значениями.
Их ценности могут действительно измениться в любое время.
Обратите внимание, что компилятор не пытается быть умным, читая каждый оператор, чтобы угадать, действительно ли a и b мутировать.
Он считает, что он может и так оценивать a + b только во время выполнения.

Теперь в этом случае, почему a + b не создает short, но int?
Поскольку JLS 8 указывает, что:

4.2.2. Целые операции

Если целочисленный оператор, отличный от оператора сдвига, имеет хотя бы один операнд типа long, то операция выполняется с использованием 64-битного точность, а результат численного оператора имеет тип long. Если другой операнд не длинный, он сначала расширяется (§5.1.5), чтобы напечатать длительное числовое продвижение по службе (§5.6).

В противном случае операция выполняется с использованием 32-битной точности и результат численного оператора имеет тип int. Если либо операнд не является int, он сначала расширен, чтобы набирать int посредством числовой рекламы.


Как примечание, если вы измените свой код, чтобы сделать a и b constants:

final short a = 1;
final short b = 2;
short c = a + b;

Теперь это будет компилироваться, так как a + b будет оцениваться как константное выражение (3).

Ответ 2

Насколько я понимаю, Java поддерживает + для int и long, но, как указано, не для краткости. Автоматического преобразования типов нет, потому что операция указана для выполнения с использованием int или long datatypes.

См. https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2

Если вы хотите получить действительный результат и знаете, что результат не вызывает переполнение, вы можете сделать результат:

short a = 1;
short b = 2;
short c = (short)(a + b);