面试题:Integer类型比较

Integer类型的比较是面试中常问的一个东西,, 涉及基本数据类型,引用数据类型的装箱拆箱,类加载机制等。首先看下面两段代码的执行结果

    public static void IntegerDemo1() {
            Integer i1 = 100;
            Integer i2 = 100;
            System.out.println(i1.hashCode());
            System.out.println(i2.hashCode());
            System.out.println("比较结果:" + (i1 == i2));
            System.out.println("比较结果:" + i1.equals(i2));
            System.out.println("比较结果:" + i1.compareTo(i2));
    }
    100
    100
    比较结果:true
    比较结果:true
    比较结果:0
    public static void IntegerDemo1() {
            Integer i1 = 200;
            Integer i2 = 200;
            System.out.println(i1.hashCode());
            System.out.println(i2.hashCode());
            System.out.println("比较结果:" + (i1 == i2));
            System.out.println("比较结果:" + i1.equals(i2));
            System.out.println("比较结果:" + i1.compareTo(i2));
    }
   200
    200
    比较结果:false
    比较结果:true
    比较结果:0    

为什么Integer的值是100和200时会出现不同的结果呢?

  首先要知道Integer i1 = 100做了什么? 在做这样的操作时,实际就是基本数据类型与引用类型之间的拆箱和装箱操作,Integer i1 = 100是一个装箱操作,本质就是Integer i1 = Integer.valueOf(100),源码如下:

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

  在valueOf方法,,对赋的值进行一个判断操作,如果值在-128~127之间,就会在内部类IntegerCache的cache[]数组中获取一个Integer对象,如果不是就new一个新的Integer对象.

那么cache[]中又是什么呢?

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

  从IntegerCache中的一段源码中可以发现cache[]中循环放入了值在-128~127之间的Integer对象,根据内部类加载机制,当类第一次调用时会初始化这个数组,并且在JVM中只初始化一次,到这里我们就明白了为什么赋值在-128~127之间的比较时能够相等,因为==比较的是内存地址,示例代码中的变量i1和i2在这个范围内都引用了从cache取出的同一个对象,对象内存地址一样,所以是相等的,在超出这个范围之后,每次创建会new一个新的Integer对象,引用的是不同的对象,所以不相等.

那为什么equals方法一直相等呢?

public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
}

可以看到Integer对equals方法进行重写,从比较两个对象的内存地址变成了比较两个Integer对象的的值,这与String类相似,同时重写的还有hashCode()方法,hashcode返回了对象的值.

那为什么要设计IntegerCache类来缓存-128~127的对象呢?

  节省内存消耗,提高程序性能,Integer是一个经常使用到的类,并且一般创建的对象值范围都在-128~127之间,并且创建这样相似值的对象并没有太大意义,所以使用IntegerCache类,与此类似的ByteCache、ShortCache等.

那Integer比较用什么方法呢?

  推荐compareTo方法,其次equals方法

posted @ 2020-06-18 15:53  哲雪君!  阅读(1329)  评论(0编辑  收藏  举报