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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© flydream 中级黑马   /  2016-8-6 22:43  /  10795 人查看  /  41 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

5黑马币
               Integer i=new Integer(3);
                Integer j=new Integer(3);
                System.out.println(i==j);
                System.out.println(i.equals(j));
               
                Integer i1=3;
                Integer j1=3;
                System.out.println(i1==j1);
                System.out.println(i1.equals(j1));
这又啥区别啊,真实醉了,

最佳答案

查看完整内容

这是包装类自动装箱拆箱的内容。正常来说,Integer i = new Integer(3);的内部流程应该是i存储着3所在的地址,直接使用i的话,取出的应该是3的地址值,而不是3本身。Integer i=3;同理,它的正常作用应该是就是把3赋值给i。但是(最重要的就是这个但是),Integer等基本数据包装类,有自动装箱和自动拆箱功能,当你使用Integer i=3;时它会自动完成Integer i=new Integer(3);的流程与功能,这是自动装箱。而当你在完成i的初始化要使 ...

41 个回复

倒序浏览
这是包装类自动装箱拆箱的内容。正常来说,Integer i = new Integer(3);的内部流程应该是i存储着3所在的地址,直接使用i的话,取出的应该是3的地址值,而不是3本身。Integer i=3;同理,它的正常作用应该是就是把3赋值给i。但是(最重要的就是这个但是),Integer等基本数据包装类,有自动装箱和自动拆箱功能,当你使用Integer i=3;时它会自动完成Integer i=new Integer(3);的流程与功能,这是自动装箱。而当你在完成i的初始化要使用i的时候,比如System.out.println(i);正常来讲,输出i的地址值,而不是3。但Java会自动通过i存储的地址值,直接找到3。这个过程叫自动拆箱。而i==j与i.equals(j),i==j比较的就是i于j的地址值,而i.equals(j)比较的是i于j地址值所代表的内容。你发的代码踩进了一个坑,所以看不出差别的。因为实际使用中,小数字使用率极高,所以为了节省内存,所有取值范围在(-128~127)之间的数字都会使用同一个值。即你以上的代码中,i j i1 j1四个变量实际上都因为Java的内部设计而指向同一个3。想看出==和equals的区别,不要使用(-128~127,这也是byte类型的取值范围)这个范围之内的数。如有帮助,忘请采纳!
回复 使用道具 举报
一个是用的引用性的,一个是常量池类型的
回复 使用道具 举报
一个是引用类型的,一个是常量池,应该是这样的
回复 使用道具 举报
第一个是创建对象的,存在堆里面,第二个只是在常量池的.integer:==是比较地址值,equals是比较内容看其是否相等!
回复 使用道具 举报

第一个用的引用类型的,第二个是常量池类型的,好好回顾一下
回复 使用道具 举报
首先,Integer类重写了equals()方法,作用为对比数据的值,所以两个都是true;
i和j是2个不同的对象(都是new出来的新的),所以i和j被赋予的地址值不一样,所以i == j为false;
i1和j1并不是new的对象,他们的地址值都是指向常量池的3这个数据,所以i1 == j1 为true。

另外注意超过byte取值范围的i == j为false
Integer i = 128;
Integer j = 128;
i == j   false
回复 使用道具 举报
上面  i     new了Interger 所以在堆内存中创建了一个对象,J同样也创建了一个对象,表明
回复 使用道具 举报
上面      i     new了Interger 所以在堆内存中创建了一个对象,
            J同样也创建了一个对象,表明地址 值不一样。
”==”号表明的是判断地址值是否一样     此处明显两个对象互不干扰  结果为为false ,
equals则判断的是内容一样就为true
下面
则是 i1 和 j1 分别指向常量池里的同一个数字
则==号判断地址值一样就返回结果true
eqauls 判断内容一样 返回结果为true
另外常量池里的数字是不能超过-128~127的
回复 使用道具 举报
本帖最后由 liusonglin 于 2016-8-8 01:29 编辑

        Integer i1 = 3;
        Integer j1 = 3;
JDK5的新特性 -- 自动装箱,以上代码等价于(通过反编译工具可以看到):
        Integer i1 = Integer.valueOf(3);
        Integer j2 = Integer.valueOf(3);
查看原码:
        // 这个是valueOf()方法的原码
        public static Integer valueOf(int i) {
                assert IntegerCache.high >= 127;
                if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
                return new Integer(i);
        }

        // 这个是Integer类中的内部类原码
        private static class IntegerCache {
                static final int low = -128;
                static final int high;
                static final Integer cache[];

                 static {
                        // high value may be configured by property
                         int h = 127;
                        String integerCacheHighPropValue =
                        sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
                        if (integerCacheHighPropValue != null) {
                                 int i = parseInt(integerCacheHighPropValue);
                                 i = Math.max(i, 127);
                                 // Maximum array size is Integer.MAX_VALUE
                                 h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                         }
                        high = h;

                        cache = new Integer[(high - low) + 1];
                         int j = low;
                         for(int k = 0; k < cache.length; k++)
                                 cache[k] = new Integer(j++);
                 }

                 private IntegerCache() {}
         }
        
        从红色标记可以得知:IntegerCache.low = -128,IntegerCache.high = 127
        针对 -128 到 127 之间的数据做了一个数据缓冲池,如果数据是该范围内的,每次并不创建新的空间,所以 i1 和 j1 的地址值相同。
回复 使用道具 举报
结果为:
false
true
true
true
回复 使用道具 举报
第一个代码创建的是引用数据类型,
第一个输出语句比较的是地址值,两个对象的地址值肯定是不同的,故而为false
第二个输出语句比较的是内容,两者都是3,故而为true

第二个代码是直接赋值为3,
第一个输出语句比较的是值,故而为true
第二个输出语句比较的是内容,也为true
回复 使用道具 举报
本帖最后由 骚动的石头 于 2016-8-9 22:32 编辑

结果为 false true true true  
你再来看这段代码.和你第二段代码类似,结果却不同
          Integer i2=200;
          Integer j2=200;
         System.out.println(i2==j2);
         System.out.println(i2.equals(j2));结果为false true
equals 就不说了   说说 ==吧
Integer i2=200;     Integer j2=200;   这两个是有包含有自动装箱的,其中用了Integer的valueOf方法
当数值是 -128 - 127 时候 Integer是有一个池来放这些数字的  所以i1与i2地址值是一样的.  
但是超过这个范围,就要在堆内存中新创建空间了,所以地址不一样



回复 使用道具 举报
哦哦 巧了这个我们今天刚学如果你把i1=128  j1=128  然后i1==j1就是false了    Integer i1=new Integer(x);//手动装箱           Integer i2=100;//自动装箱这是jdk1.5的新特性~~建议你多看看笔记~~~考试可能要考
回复 使用道具 举报
上面的是引用数据类型  下面的是常量  基本数据
回复 使用道具 举报
运行结果:
false
true
true
true
原因解析:
== 判断的是地址值是否相等,即是否同一个对象
Integer 中 的equals方法 是判断 Integer 值是否相等
1、第一个由于是new 对象,两个语句创建两个对象分配两个地址值;
      ==判断地址值,由于地址值不一样则返回false;
      equals判断Integer 值是否相等 ,3 等于3,故返回true;
2、第二个属于装箱,由于右边属于常量,在编译时,编译器会将常量在内存方法区中的常量池中进行常量对象创建,为了避免重复创建常量,编译器有常量优化机制,在进行常量创建时,首先进行检索,看常量池是否存在相同常量,如果存在则直接引用,不再进行新建。
      故第一次创建常量对象后,第二次直接引用该常量。即两者引用指向相同对象。
      ==判断地址值,由于指向同一对象,故地址值相等,返回true;
        equals判断Integer 值是否,同一对象,故返回true。
----------------------------------------------------
Integer 中 equals 的源代码
public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

-----------------------------------------------------

回复 使用道具 举报
一个是对象 引用类型 一个是常量
回复 使用道具 举报
一个引用类型,一个常量类型,一个在堆里进行,一个在栈里进行
回复 使用道具 举报
这个是自动装箱和自动拆箱的操作,]
new的话就是在堆区新建了一个对象,所以地址值就不一样
但是在常量池中就会有一个匹配一个整型包装类
所以呢,这是有区别的,
回复 使用道具 举报
new Integer,是创建两个对象,Integer I=97对象是从常量池里面拿的
回复 使用道具 举报
123下一页
您需要登录后才可以回帖 登录 | 加入黑马