这是我的代码:
Integer x=5;
int y=x+x;
System.out.println(y);
我的问题很简单。在第一线显然有一个拳击发生。但在下一行,是否有两个拆箱或一个?我的问题实际上意味着:两个整数实例x是否已取消装箱,添加,然后存储在int y变量中,或者两个整数是否作为整数实例添加,然后结果是否已取消装箱并存储? 附:请注意,除了帮助我理解拆箱的概念之外,上述代码不起作用。 非常感谢你的时间!
答案 0 :(得分:3)
我会说 2次拆箱转换会发生。
x
的类型绝对是Integer
,算术表达式x + x
要求两个操作数都被取消装箱。 JLS § 15.5表示
如果表达式的类型是基本类型,则表达式的值具有相同的基本类型。
另外,根据§ 15.18.2,
对操作数执行二进制数字提升(第5.6.2节)。
请注意,二进制数字促销执行值集转换(第5.1.13节)并可执行拆箱转换(第5.1.8节)。
数字操作数上的加法表达式的类型是其操作数的提升类型。
因此,这种算术表达式的结果类型是原始数字类型,因此x + x
会产生int
。
此结果存储在y
中,无需转换。
答案 1 :(得分:1)
我确实检查了编译器产生的内容:
"cwd": "${workspaceFolder}/src/project"
汇编为:
str1 = 'JUNKINFRONThttp://francium.tech'# should be http://francium.tech
str2 = 'JUNKINFRONThttp://francium.tech/http'# should be http://francium.tech/http
str3 = 'francium.tech/http' #should be francium.tech/http (unaffected)
str4 = 'JUNKINFRONThttps://francium.tech/http'# should be https://francium.tech/http
[str1, str2, str3, str4].each do |str|
puts str.gsub(/^.*(http|https):\/\//i, "\\1://")
end
Result:
http://francium.tech
http://francium.tech/http
francium.tech/http
https://francium.tech/http
我们通过调用静态方法package test;
public class Dummy {
public static void main(String[] args) {
Integer x=5;
int y=x+x;
System.out.println(y);
}
}
来查看文字Compiled from "Dummy.java"
public class test.Dummy extends java.lang.Object{
public test.Dummy();
Code:
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_5
1: invokestatic #16; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
4: astore_1
5: aload_1
6: invokevirtual #22; //Method java/lang/Integer.intValue:()I
9: aload_1
10: invokevirtual #22; //Method java/lang/Integer.intValue:()I
13: iadd
14: istore_2
15: getstatic #26; //Field java/lang/System.out:Ljava/io/PrintStream;
18: iload_2
19: invokevirtual #32; //Method java/io/PrintStream.println:(I)V
22: return
}
的装箱,并且我们使用5
看到java/lang/Integer.valueOf:(I)Ljava/lang/Integer
变量的两个拆箱。添加结果立即作为基元存储到x
变量中,而不进行装箱/拆箱。
但仍然是Hotspot运行时优化器,如果他发现java/lang/Integer.intValue:()I
总是10,我不会感到惊讶。
答案 2 :(得分:0)
我做了三个;至少在概念上(即假设没有明显的优化)。
对于x
的左参数, +
一次取消装箱,再次为+
的右参数取消装箱。
该表达式的结果类型必须是Integer
,因此int
会被设置为Integer
,其值为10.转换回{时,会再次取消装箱在int
的作业中{1}}。
请注意,5和10都在整数缓存中(y
的一部分),因此实际上不会创建其他对象。