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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张世威 中级黑马   /  2013-5-23 14:12  /  1848 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 张世威 于 2013-5-24 11:07 编辑
  1. public class Questtion {
  2.         public static void main(String[] args) {
  3.                 Integer i1=3;
  4.                 Integer i2=3;
  5.                 Integer i3=new Integer(3);
  6.                 Integer i4=new Integer(3);
  7.                 Integer i5=Integer.valueOf(3);
  8.                 Integer i6=Integer.valueOf(3);
  9.                
  10.                 System.out.println(i1==i2); //true
  11.                 System.out.println(i3==i4);//false
  12.                 System.out.println(i5==i6);//true
  13.                
  14.                 System.out.println(i1==i3);//false
  15.                 System.out.println(i1==i5);//true
  16.                

  17.                
  18.         }

  19. }
复制代码
//①i1到i6都是不同的对象,最后结果发现,i1==i2==i5==i6,而i3、i4与其他的都不等.
//②按道理说,这6个对象都是引用类型,它们的地址都是不一样的,结果应该都是false,这是为什么?
//③上面 i1和i2、i3和i4、i5和i6的初始化有什么不同?

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

11 个回复

倒序浏览
占个楼。。
回复 使用道具 举报
1.当数值在byte范围内,如果该数值已经存在,就不会在内存开辟新空间了。所以i1==i2为true... i3 i4都new了新的对象所以i3==i4为false...i5==i6和i1=i2同理,只不过这里是通过Integer.Valueof()赋值。
2.如上所说, i1 i2 i5 i6地址是相同的。

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

回复 使用道具 举报
至于初始化应该都是初始化了Integer类中的方法吧。
回复 使用道具 举报
本帖最后由 孙茜茜 于 2013-5-23 14:34 编辑

3,4是在堆new出来的新对象,各自指向自己的对象,尽管对象里的值相等
1,2初始化的就是数值,定义2的时候能够在池中找到相同内容的对象,于是1和2都指向那个对象
5,6我不敢太肯定,我查了一会觉得是他们都在池里找"3"这个对象,找到了就指向这个对象,其实就是定义1的时候那个"3"

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

回复 使用道具 举报
i1、i2的情况是属于JVM优化的原因,当数值在byte范围之内,即-128~127时,如果该数值已经存在,JVM不会开辟新的内存空间赋值而是直接指向原有值地址。i3、i4的情况是创建两个内容相同的Integer对象,由于地址不同,很好理解i3==i4为false。i5、i6的情况,valueOf(int i)方法是返回一个表示指定int值的Integer实例,地址指向是和i1、i2的一样的。

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

回复 使用道具 举报
首先你得有堆和栈的概念,每一个方法在堆中开辟一个空间,如你上面的i1和i2在堆中是一样的(就是地址一样),而通过new创建的对象则是存放在栈中(就是通过返回的栈地址来引用的),所以同一个类通过new创建的所有对象都是不同的(返回的栈地址不同!!)。如果还有不懂的话可以借鉴毕向东老师的有关内存地址视频

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

回复 使用道具 举报
本帖最后由 张世威 于 2013-5-23 15:20 编辑
江南雨 发表于 2013-5-23 14:37
首先你得有堆和栈的概念,每一个方法在堆中开辟一个空间,如你上面的i1和i2在堆中是一样的(就是地址一样) ...

你好像说反了。。。。堆-引用类型  、栈-基本类型

i1和i2都是Integer类型对象,应该是放在堆中。

回复 使用道具 举报
这个问题有点技术含量,超出我的水平了哦
回复 使用道具 举报
  前提是:3 没有超过一个字节           
                  System.out.println(i1==i2); //true
原因:3是今本数据类型,Integer i = 3;是1.5的新特性,将基本数据类型进行了装箱操作。i1和i2都是3.
                System.out.println(i3==i4);//false
原因:new一个对象,是在堆内存中开辟一片空间,每new一次,开辟的空间就不一样。
                System.out.println(i5==i6);//true
原因:显式的装箱操作。其实还是3   

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

回复 使用道具 举报
孙茜茜 发表于 2013-5-23 14:24
3,4是在堆new出来的新对象,各自指向自己的对象,尽管对象里的值相等
1,2初始化的就是数值,定义2的时候能 ...

不能这么说, 12初始化的不是数值,也是在堆内存中的对象。只不过新特性规定byte范围内的数值不会开辟新的内存空间而已,所以12指向同一个内存地址
回复 使用道具 举报
大概理解了,谢谢大家了。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马