黑马程序员技术交流社区

标题: 关于Integer的自动装箱和自动拆箱 [打印本页]

作者: 高原    时间: 2012-7-5 20:44
标题: 关于Integer的自动装箱和自动拆箱
本帖最后由 高原 于 2012-7-6 07:41 编辑

我写了一段程序:
  1. public class IntegerTest {
  2.         public static void main(String[] args) {
  3.                 int i1 = 100;
  4.                 Integer i2 = 100;
  5.                 Integer i3 = 100;
  6.                 Integer i4 = new Integer(100);
  7.                 Integer i5 = new Integer(100);
  8.                
  9.                 System.out.println(i1 == i2);  //true
  10.                 System.out.println(i2 == i3);  //true
  11.                 System.out.println(i1 == i4);  //true
  12.                 System.out.println(i2 == i4);  //false
  13.                 System.out.println(i4 == i5);  //false
  14.         }

  15. }
复制代码
1.为什么同样都是引用类型  i2 == i3 为true,而 i4 == i5 就false?
2.为什么同样是比较地址  i1 == i4 为true,而 i2 == i4 就false?

作者: 孙飞    时间: 2012-7-5 20:52
本帖最后由 feigecal 于 2012-7-5 21:47 编辑

对于新特性,你的Integer i2 = 100其实是调用的valueOf(int  i)返回一个表示指定的int值的Integer实例,当数值在Byte范围内时,也就是-128到127之间时,java在Integer中有事先缓存好的原型对象,每次返回的都是同一个对象,只有不在这个范围内时才会new一个Integer对象,因为100在Byte范围内,所以不会开辟新的空间,所i1  i2  i3都指向的是同一个对象,i4   i5并没有使用新特性,而是指定了要在堆内存中分别开辟一个空间,引用 不同,所以是false,因为i1是基本类型变量,直接存在于栈内存中的,基本类型和对象比是比较的值,因为i1和i4的值是相等的所以为true
  1. public class IntegerTest
  2. {
  3.         public static void main(String[] args)
  4.        {
  5.                 Integer i2 = 100;
  6.                 Integer i3 = 100;
  7.                 Integer i4 = Integer.valueOf(100);
  8.                System.out.println(i2 == i3);
  9.                System.out.println(i2 == i4);
  10.        }
  11. }
复制代码
这样结果都为true

作者: 赵倩倩    时间: 2012-7-5 20:57
Integer是int的封装对象,两个对象==比较的是栈的值
Integer i4 = new Integer(100);
  Integer i5 = new Integer(100);
i4与i5存的是Integer的堆中的地址,而不是值
i4,i5指向堆中的地址显然不同所以i4==i5为false

int i1= 1oo; int为值类型,引用类型Integer与值类型int比较显然比较的是值
所以i1==i4比较的是他们各自的value, i1==i4为true

new 创建新的内存,直接赋值则不一定创建新的内存
因为i4的引用指向堆,而i2指向专门存放他的内存,所以他们的内存地址不一样
所以i2==i4为false

作者: 黄克帅    时间: 2012-7-5 20:58
本帖最后由 黄克帅 于 2012-7-5 20:59 编辑

1.为什么同样都是引用类型  i2 == i3 为true,而 i4 == i5 就false?
Integer i2 = 100  Integer i3 = 100;
有个自动装箱的过程,这是jdk1.5后的新特性。  等于new Integer(100);  但是这个新特性有个特点,就是 在byte范围内 ,如果存在了一个值,再创建的时候就不会重新创建,而是用 原来那个。  但是超过byte范围  还是会新建的  比如  Integer i2 =128 Integer i3 = 128;  你再比较就是false   。 至于而 i4 == i5 就false? 很明显,没new一次就创建一个新对象,本来就是两个对象,当然false

2.为什么同样是比较地址  i1 == i4 为true,而 i2 == i4 就false?
基本数据类型和对象比较的时候  对象应该是自动拆箱为 基本数据类型再比较 ,这样他们比较的就是 里面的值 而不是地址,所以i1 == i4 为true
对象和对象比较的是地址,i2   i4 是两个对象  当然false




作者: 黄克帅    时间: 2012-7-5 21:16
黄克帅 发表于 2012-7-5 20:58
1.为什么同样都是引用类型  i2 == i3 为true,而 i4 == i5 就false?
Integer i2 = 100  Integer i3 = 100; ...

个人是这样想的   具体是不是拆箱为基本数据类型进行比较  就不知道了。但是可以确定他们进行的是  值 的比较
作者: 黑马-李勇    时间: 2012-7-5 21:20
i2==i3我认为是
因为常量池中有了100,i2,i3都指向这个。
i4,i5是new出来的,在堆中,所以不一样。
i4小于127,不开辟新空间,只是指向常量池中的100。
i2和i3存的位置和其他的不一样,至于存哪,我忘了,不能乱说

作者: 陆强强    时间: 2012-7-5 21:20
本帖最后由 陆强强 于 2012-7-5 21:30 编辑

老办法解决,画图。
i1和i4比较的是值,都是100

未命名1.JPG (20.74 KB, 下载次数: 34)

未命名1.JPG





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2