Java中int跟Integer的区别

在了解int跟Integer的区别与联系之前需要先了解Java的自动装箱跟拆箱机制,可以看我的另一篇文章Java中自动装箱与拆箱详解。

Integer是int的包装类。Java为每一种基本数据类型都配备了相应的包装类,如下表所示:

基本数据类型 byte short int long float double char boolean
对应的包装类 Byte Short Integer Long Float Double Character Boolean

我们通过一个示例来看一下二者之间的区别:

public class IntAutoUnboxing {
    public static void main(String[] args) {
        int i = 13;

        Integer iObject1 = 13;
        Integer iObject2 = 13;

        Integer iObject3 = 129;
        Integer iObject4 = 129;

        Integer iObject5 = new Integer(13);
        Integer iObject6 = new Integer(129);

        System.out.println(iObject1 == i);//1.输出为true

        System.out.println(iObject1 == iObject2);//2.输出为true

        System.out.println(iObject3 == iObject4);//3.输出为false

        System.out.println(iObject1 == iObject5);//4.输出为false

        System.out.println(iObject3 == iObject6);//5.输出为false
    }

对上面的输出结果,我们进行逐个分析:
1.基本数据“==”是比较数值大小是否相等;引用类型“==”是比较是否指向同一个引用。
在输出语句1中,iObject1跟i进行比较,输出结果为true。当Integer类型跟int类型比较时,其中包含的过程是Integer类型首先会自动拆箱成int类型的数值,然后再进行数值大小的比较。iObject1首先自动拆箱成int类型的数值13,然后跟i进行比较,二者数值相同,所以输出为true。

2.都是对两个Integer类型的比较,为什么输出语句2输出为true,而输出语句3却输出为false?这还得从Integer的源码进行解释:
Integer iObject1=13这个赋值过程中包含了自动装箱:将int类型的13自动装箱成了Integer类型的13。Integer iObject1=13实质上是Integer iObject1=Integer.valueOf(13),编译器帮我们自动调用了valueOf()这个方法,所以需要从valueOf()这个方法的源码入手,看一下它的源码:

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

IntegerCache是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) {
                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之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象,如果不在这个范围内,则每次赋值都会产生一个新的Integer对象。
输出语句2中Integer的值都是13,13在-128到127这个范围内,iObject3跟iObject4会指向常量池中同一个对象,所以输出为true。而输出语句3中Integer的值都是129,已经超出了-128到127这个范围,因此会创建两个Integer对象,两个独立的对象肯定不会指向同一个引用,所以输出为flase。

3.iObject1跟iObject5都是13,在-128到127这个范围内,为什么输出为false?原因很简单,因为iObject5使用了关键字new创建了一个新的对象,iObject1是常量池中的Integer对象,iObject5是使用关键字new新创建的对象,两个对象相互独立,肯定不会指向同一个引用,因此输出为false 。

以上1、2、3点就是int跟Integer的区别跟联系。

你可能感兴趣的:(Java基础)