A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Rockray 高级黑马   /  2013-11-17 11:56  /  1931 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 Rockray 于 2013-11-17 12:00 编辑
  1. class IntegerDemo2{
  2.         public static void main(String[] args){
  3.                 //Integer x = new Integer(4);
  4.                 Integer x = 4; //自动装箱,4是一个对象,相当于 new Integer(4)
  5.                 x = x + 2;  //x+2: x进行了自动拆箱,变成了int类型,和2进行加法运算,再将和进行装箱赋给x。
  6.                                 //自动拆箱:x.intValue();
  7.         }
  8.         
  9.         public static void sop(Object obj){
  10.                 System.out.println(obj);
  11.         }
  12. }
复制代码
上面代码中,
Integer  x = 4;
x = x + 2;   之后,内存中是不是存在了两个Integer对象?
因为,x+2  后是不是多了个值为6的Integer对象? 然后把这个新对象的地址值赋给了x,原来值为4的Integer对象就没被引用了?

还是说原来值为4的Integer对象的内容变成了6,而自始至终还是只有这一个对象?

评分

参与人数 1技术分 +1 收起 理由
狼王 + 1 赞一个!

查看全部评分

7 个回复

倒序浏览
我认为 x=x+2 后是又new了一个对象,

也就是说内存里有了两个对象 1,new Integer(4) ; 2, new  Integer(6)
x重新赋值指向new Integer(6)的地址

以上纯属个人观点,未经求证。。坐等大神解释。。
回复 使用道具 举报
java对于Integer与int的自动装箱与拆箱的设计,是一种模式叫享元模式
在自动装箱时对于值从–128到127之间的值,它们被装箱为Integer对象后,会存在内存中被重用,始终只存在一个对象;而如果超过了这个范围的值,被装箱后的Integer对象并不会被重用,即相当于每次装箱时都新建一个Integer对象。
回复 使用道具 举报
Integer类的内部, 有一个常量静态数组, 在Integer类被加载的时候, 预先创建了-128 ~ 127的Integer对象, 所以当声明的Integer类型变量的值在-128 ~ 127的范围内时, 不会新创建对象, 直接引用数组中创建好的。所以你上面的x = x + 2执行之后应该是只有一个对象,如果超出-128 ~ 127这个范围就会创建新的对象了吧,

个人的理解。如有问题一起讨论

评分

参与人数 1黑马币 +4 收起 理由
枫儿 + 4 赞一个!

查看全部评分

回复 使用道具 举报
雪龙 发表于 2013-11-17 12:30
Integer类的内部, 有一个常量静态数组, 在Integer类被加载的时候, 预先创建了-128 ~ 127的Integer对象, 所 ...

你好,
按照你的理解,4 和 6 都是-128~127之间的,那么 Integer x = 4; 和 x = x +2;
都是引用的常量静态数组中的 4 和 6 吗?
这样的话好像没有创建对象啊,因为都是引用的常量静态数组中的,那么常量静态数组中的元素是一个个对象吗?
感觉理解起来好费劲
回复 使用道具 举报
本帖最后由 赵晓海 于 2013-11-17 14:35 编辑

享元模式的具体过程:
如果一个int类型的数据在 -128~127 之间(即一个字节),当把它包装成一个Integer类型时,会把这个数据放在一个缓冲池中,在下次把同一个数据包装成Integer类型时,就直接去缓冲池中拿,这就是设计模式中的享元模式
看下面的代码
  1. public class IntegerTest {
  2.     public static void main(String[] args) {
  3.        Integer integer1 = 127;
  4.        Integer integer2 = 127;
  5.        Integer integer3 = 128;
  6.        Integer integer4 = 128;
  7.        System.out.println(integer1 == integer2);
  8.        System.out.println(integer3 == integer4);
  9.     }
  10. }
复制代码

integer2integer1拿到的是同一个对象,对应的当然是同一个地址,因此打印结果为true

Integer integer3 = 128;   会新建一个对象,假设对象的地址是address3,对象内容是128
Integer integer4 = 128;   也会新建一个对象,假设对象的地址是address4,对象内容也是128
因为 “integer3 == integer4” 比较的是两个对象的地址而不是对象的内容,显然地址是不一样的,因此返回false

再来看你的代码:
  1. <font color="black">class IntegerDemo2{
  2.         public static void main(String[] args){
  3.                 //Integer x = new Integer(4);
  4.                 Integer x = 4; //自动装箱,4是一个对象,相当于 new Integer(4)
  5.                 x = x + 2;  //x+2: x进行了自动拆箱,变成了int类型,和2进行加法运算,再将和进行装箱赋给x。
  6.                                 //自动拆箱:x.intValue();
  7.         }
  8.         public static void sop(Object obj){
  9.                 System.out.println(obj);
  10.         }
  11. }</font>
复制代码
根据开头的描述,执行此句时Integer x = 4;先将4包装成Integer类型,然后将它放入缓冲池。此时堆内存中有一个对象 4
x = x + 2; 自动拆箱,运算,将运算结果6自动装箱,装箱后也将6放入缓冲池。这个过程中,先创建一个对象2,然后运算,重新创建一个对象6。最后x断开指向4的引用,转而指向6。


因此堆内存中有3个对象:2、4、6,但是2,4由于没有被指向,所以成了垃圾,
而缓冲池中有两个对象分别是4,6。


评分

参与人数 1技术分 +1 收起 理由
FFF + 1 赞一个!

查看全部评分

回复 使用道具 举报
Rockray 高级黑马 2013-11-17 14:36:08
7#
赵晓海 发表于 2013-11-17 14:20
享元模式的具体过程:如果一个int类型的数据在 -128~127 之间(即一个字节),当把它包装成一个Integer类型 ...

谢谢你的解答,好详细,
x = x + 2;这部中,2 也是一个对象吗?
x自动拆箱,然后x不就是一个int类型吗,再加的2不也应该是int类型吗?加完后把结果 6 自动装箱,就新建了一个对象,这样理解对不对?
回复 使用道具 举报
Rockray 发表于 2013-11-17 14:36
谢谢你的解答,好详细,
x = x + 2;这部中,2 也是一个对象吗?
x自动拆箱,然后x不就是一个int类型吗, ...

x已经被定义成了Integer类型了,如果没有转换,它的类型不会改变。拆箱的时候拆的是被Integer封装起来的“4”,把“4”变成int型。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马