发生了多少次拆箱?

时间:2018-02-02 13:44:49

标签: java integer int boxing unboxing

这是我的代码:

Integer x=5;
int y=x+x;
System.out.println(y);

我的问题很简单。在第一线显然有一个拳击发生。但在下一行,是否有两个拆箱或一个?我的问题实际上意味着:两个整数实例x是否已取消装箱,添加,然后存储在int y变量中,或者两个整数是否作为整数实例添加,然后结果是否已取消装箱并存储? 附:请注意,除了帮助我理解拆箱的概念之外,上述代码不起作用。 非常感谢你的时间!

3 个答案:

答案 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的一部分),因此实际上不会创建其他对象。