1 + 2
is a constant expression while a + b
is not.
It matters on the evaluation of them.
The first one will be done at compile time, the second one at runtime.
The JLS 8 states :
15.28. Constant Expressions
A constant expression is an expression denoting a value of primitive
type or a String that does not complete abruptly and is composed using
only the following:
Literals of primitive type and literals of type String (§3.10.1,
§3.10.2, §3.10.3, §3.10.4, §3.10.5)
Casts to primitive types and casts to type String (§15.16)
The unary operators +, -, ~, and ! (but not ++ or --) (§15.15.3,
§15.15.4, §15.15.5, §15.15.6)
The multiplicative operators *, /, and % (§15.17)
The additive operators + and - (§15.18)
........................
Here :
short c = 1 + 2;
1 + 2
is composed of two int
literals and one additive operator.
So it is considered as a constant expression.
Constant expressions are evaluated at compile time.
So short c
is evaluated as 3
Here is a sample class :
package stackoverflow;
public class EvaluationClass {
public void foo(){
short c = 1 + 2;
}
}
Here is the disassembled code :
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
}
We can see the 0: iconst_3
instruction that loads the 3
int
onto the stack.
Whereas here :
short a = 1;
short b = 2;
short c = a + b;
a + b
is evaluated only at runtime as a
and b
are not constant values.
Their values may indeed change at anytime.
Note that the compiler doesn't try to be clever by reading each statement to guess if a
and b
effectively mutate.
It considers that it may and so evaluate a + b
only at runtime.
Now in this case, why a + b
doesn't produce a short
but an int
?
Because the JLS 8 specifies that :
4.2.2. Integer Operations
If an integer operator other than a shift operator has at least one
operand of type long, then the operation is carried out using 64-bit
precision, and the result of the numerical operator is of type long.
If the other operand is not long, it is first widened (§5.1.5) to type
long by numeric promotion (§5.6).
Otherwise, the operation is carried out using 32-bit precision, and
the result of the numerical operator is of type int. If either operand
is not an int, it is first widened to type int by numeric promotion.
As a side note, if change your code to make a
and b
constants
:
final short a = 1;
final short b = 2;
short c = a + b;
This will compile fine now as a + b
would be evaluated as a constant expression (3
).