为什么 "short thirty = 3 * 10" 是合法的赋值?
Why is "short thirty = 3 * 10" a legal assignment?
如果在算术运算中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
。
数字文字有什么特别之处吗?
是的,字面大小写有一些特殊之处:10 * 3
将在 compile 时计算。所以你不需要对乘法文字进行显式 (short)
转换。
ten * three
编译时不可评估,因此需要显式转换。
如果ten
和three
标记为final
就另当别论了。
因为编译器在 编译时 本身将 10*3
替换为 30。所以,实际上: short thirty = 10 * 3
是在编译时计算的。
尝试将 ten
和 three
更改为 final short
(使它们成为编译时间常量),看看会发生什么:P
使用 javap -v
检查两个版本(10*3
和 final short
)的字节码。你会发现差别不大。
好的,所以,这是不同情况下的字节码差异。
案例-1 :
Java Code :
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
在上面的例子中,10
和3
取自局部变量s1
和s2
以下 answer 添加了 JLS 部分和有关此行为的一些详细信息。
根据JLS §15.2 - Forms of Expressions
Some expressions have a value that can be determined at compile time.
These are constant expressions (§15.28).
如果在算术运算中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
。
数字文字有什么特别之处吗?
是的,字面大小写有一些特殊之处:10 * 3
将在 compile 时计算。所以你不需要对乘法文字进行显式 (short)
转换。
ten * three
编译时不可评估,因此需要显式转换。
如果ten
和three
标记为final
就另当别论了。
因为编译器在 编译时 本身将 10*3
替换为 30。所以,实际上: short thirty = 10 * 3
是在编译时计算的。
尝试将 ten
和 three
更改为 final short
(使它们成为编译时间常量),看看会发生什么:P
使用 javap -v
检查两个版本(10*3
和 final short
)的字节码。你会发现差别不大。
好的,所以,这是不同情况下的字节码差异。
案例-1 :
Java Code : 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
在上面的例子中,10
和3
取自局部变量s1
和s2
以下 answer 添加了 JLS 部分和有关此行为的一些详细信息。
根据JLS §15.2 - Forms of Expressions
Some expressions have a value that can be determined at compile time. These are constant expressions (§15.28).