为什么“ short three = 3 * 10”是一个合法的转让?

如果 short在算术运算中自动升级为 int,那么为什么是:

short thirty = 10 * 3;

short变量 thirty的合法赋值?

反过来,这个:

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

不能编译,因为如果没有按照预期进行强制转换,则不允许将 int值分配给 short

关于数字字面值有什么特别的吗?

6273 次浏览

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.

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).