前言
在刷软中的时候涉及到了值传递和地址传递传参的区别,其中提到不管是将基础数据类型的变量传值给对象数据类型的变量还是反过来都属于值传递,究其原因就是期间发生了自动装箱和拆箱,所以特地去查了相关资料
一、拆装箱的实质
以Intrger为例子
Integer i =520;
等价于Integer i = Integer.valueOf(520)
,jvm偷偷帮你做了转化操作(快说 谢谢jvm)
在查阅资料中有些说是等价于 Integer i = new Integer(520)
的,我自己验证了一下并不是,情况如下图
Integer i1 = new Integer(520); int i2 = it1;
这种属于自动拆箱等价于int i2 = it1.intValue();
二、拓展
1.数值超过128的Integer装箱
Integer的数值范围在-128-127之间,如果不在这个区间则会再创建一个对象再返回,所以第二个判断是false。详情见Integer类的valueOf
2.Java内存分配
由于自动装箱拆箱的问题联想到创建对象个数,并且前辈跟我说下面的代码是创建了三个对象,很迷惑,特地去查了下相关资料
String str1=“ab”; str1=str1+”c“;
原来执行String str1=“ab”的时候,jvm会去常量池找ab,如果找到,则不再创建新的对象,直接返回已存在对象的引用;如果没找到,则先创建这个对象,然后把它加入到常量池中,再将它的引用返回。同理执行 str1=str1+”c“;时会先创建c放在常量池,然后再创建abc到常量池,所以是三个对象
如果再执行,String str2=“abc”;就不会创建对象了,直接将str2指向常量池的ab
同样的,String s1=new String(“鲁智深”)会先在常量池里找abc,没有找到就创建。然后由于new String(),每new一个对象就会在堆中新建一个对象,不管这个值是否相同;所以是创建两个对象
如果再执行String s2=new String(“鲁智深”)只会创建一个对象abc到堆中
存储情况如下图所示
说明:
栈:存放函数定义的一些基本类型的变量数据和对象的引用变量
堆:存放由new创建的对象和数组,在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理
常量池:存放各种用final修饰的基本类型和对象型(数组集合等)的值(即常量)
钱塘江上潮信来,今日方知我是我