对Integer、int、Integer.valueOf()、new Integer()之间进行==和equals的比较|自动装箱和自动拆箱

先直接来看例子!

import org.omg.PortableInterceptor.INACTIVE;

public class Test {
    public static void main(String[] args) {
        int c0=100;
        int c01=100;

        Integer c10=100;
        Integer c11=100;

        Integer c20=Integer.valueOf(100);
        Integer c21=Integer.valueOf(100);

        Integer c30=new Integer(100);
        Integer c31=new Integer(100);
        
        System.out.println("以下所有比较的数值都是相等的。");
        System.out.println("两个int类型==比较:"+(c0==c01));
        System.out.println("int类型和Integer==做比较:"+(c0==c11));
        System.out.println("两个Integer类型==比较:"+(c10==c11));
        System.out.println("两个Integer.valueOf类型  ==比较:"+(c20==c21));
        System.out.println("Integer类型和int类型  ==比较:"+(c20==c0));
        System.out.println("Integer类型和Integer.value  ==比较:"+(c20==c10));
        System.out.println("两个Integer new类型  ==比较:"+(c30==c31));//f
        System.out.println("Integer new类型和int类型  ==比较:"+(c30==c21));//f
        System.out.println("Integer new类型和Integer.valueOf类型  ==比较:"+(c30==c10));//f
        System.out.println("Integer new类型和int类型  ==比较:"+(c30==c0));//t

    }
}

在这里插入图片描述
在赋予的值 和new的值都为同一个数的情况下
1其中c0==c01是两个int基本数据类型,其值保存在栈内存中,双等号“ == ”,对于基本数据类型,比较的是它们的值,所以是true。且不是对象,无法用equals做比较

2其中c0==c11一个是基本数据类型,一个是包装器类型,而包装类过程会new一个对象,c11会指向那个对象内存地址。
Integer c11=100;这里涉及到自动装箱过程,100是整型常量,经包装使其产生一个引用并存在栈中指向这个整型常量所占的内存,这时c11就是Integer 的引用。
当一个基础数据类型与封装类进行==、+、-、*、/运算时,会将封装类进行 拆箱,对基础数据类型进行运算。
而Integer产生的对象在与int基本数据类型的数据做比较的同时,会进行一个自动拆箱,即

Integer i = 10; //装箱
int t = i; //拆箱,实际上执行了 int t = i.intValue();

所以这个时候就变成了两个int类型==做比较,所以返回值是true!

关于equals,System.out.println(“Integer和int equals做比较:”+(c10.equals(c0)));//里面进行一个Integer与int比较 返回true

3其中c10==c11二者都是Integer c10=100,系统会自动进行Integer i = Integer.valueOf(100);
这其中还涉及到一个cache的知识,即jdk为了节省空间,在选定了一个范围为[-128到127]之间设定了一个常量池,

 public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

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) {
                try {
                    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);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

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

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

这段代码的作用是,在Integer类装载入内存时,把[-128, 127]范围内的整型数据装包成Integer类,并将其对应的引用放入到cache数组中。

而Integer.valueOf(int i);会自动对i进行一个判断,看它是否在-128~127之间 这个区间的int型数值,在常量池中已经有,相当于一个静态缓存(也是一个内存空间而不是一个基本数据类型,在做比较的时候在进行自动拆箱)。
不在的话就在new一个
所以 这一点就是如果值在范围内 二者是相等的,两个引用都指向同一个对象,
否则不等。

5重点:Integer c10=100;会自动调用Integer.valueOf(int i);
Integer.valueOf(int i);会判断是否在常量池cache中,在的话后面都引用指向同一个,不在的话就new一个新的对象
而如果是new Integer(); 这里就直接新建一个对象了,所以当他和其他的Integer做==比较时都是指向了两个不同的内存空间,不会用常量池cache中的值。

而equals() 比较的是两个对象的值(内容)是否相同(重写了)。所以更容易理解就不说了。

参考:
java的自动装箱与拆箱详解
Java的Integer.valueOf()初窥
什么是Java中的自动拆装箱

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值