为什么“short 30 = 3 * 10”是一个合法的任务?

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

 short thirty = 10 * 3; 

一个shortvariables的法定分配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

数字文字有什么特别的吗?

因为编译器本身在编译时用编译器replace了10*3 。 所以,有效地:在编译时间计算short thirty = 10 * 3

尝试改变tenthree final short (使他们编译时间常量),看看会发生什么:P

使用javap -v检查两个版本的字节码( 10*3final short )。 你将能够看到没有什么区别。

好的,所以,这里是不同情况下的字节码差异。

情况1 :

Java代码:main(){short s = 10 * 3; }

字节码:

 stack=1, locals=2, args_size=1 0: bipush 30 // directly push 30 into "s" 2: istore_1 3: return 

情况-2:

 public static void main(String arf[]) { final short s1= 10; final short s2 = 3; short s = s1*s2; } 

字节码:

  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 

情况-3:

 public static void main(String arf[]) throws Exception { short s1= 10; short s2 = 3; int s = s1*s2; } 

字节码:

 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 

在上述情况下, 103取自局部variabless1s2

是的,在字面情况下有一些特殊的情况:在编译时将会评估10 * 3 。 所以你不需要一个明确的(short)转换乘以文字。

ten * three不是编译时可评估的,所以需要一个明确的转换。

如果tenthree标记为final那将是另一回事。

以下答案添加了JLS部分和关于此行为的一些细节。

根据JLS§15.2 – expression式的forms

有些expression式的值可以在编译时确定。 这些是常量expression式(§15.28)。

Interesting Posts