Why is "short thirty = 3 * 10" a legal assignment?
Because the compiler replaces 10*3
with 30 at compile time itself. So,effectively : short thirty = 10 * 3
is calculated at compile time.
Try changing ten
and three
to final short
(making them compile time constants) and see what happens :P
Examine byte-code using javap -v
for both verisions (10*3
and final short
). You will be able to see that there is little difference.
Ok, So, here is the byte code difference for different cases.
Case -1 :
Java Code : main() { short s = 10*3; }
Byte code :
stack=1, locals=2, args_size=1
0: bipush 30 // directly push 30 into "s"
2: istore_1
3: return
Case -2 :
public static void main(String arf[]) {
final short s1= 10;
final short s2 = 3;
short s = s1*s2;
}
Byte code :
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
Case -3 :
public static void main(String arf[]) throws Exception {
short s1= 10;
short s2 = 3;
int s = s1*s2;
}
Byte-code :
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
In the above case, 10
and 3
are taken from the local variables s1
and s2
The following answer adds the JLS section and some details about this behavior.
As per JLS §15.2 - Forms of Expressions
Some expressions have a value that can be determined at compile time. These are constant expressions (§15.28).
Yes there is something special going on with the literal case: 10 * 3
will be evaluated at compile time. So you don't need an explicit (short)
conversion for multiplied literals.
ten * three
is not compile-time evaluable so therefore needs an explicit conversion.
It would be a different matter if ten
and three
were marked final
.