Ответ 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
).