Integer相同的值为什么比较出来的是false,差点丢了饭碗|8月更文挑战

328 阅读2分钟

前言

  • 今天在公司遇到一个坑,被经理骂惨了他说为什么我连一个简单的比对工作都做不好?
  • 刚接到这个问题我是一脸懵逼,我怎么可能连比对都不会?打开代码定位一开两个整数用==没毛病啊

知识梳理

  • 将128 构建给两个Integer对象。你觉得他们是相同的吗
  • 将127构建给两个Integer对象。你觉得他们是相同的吗
public static void main(String[] args) throws InterruptedException {
    Integer i1=128;
    Integer i2=128;
    Integer i3=127;
    Integer i4=127;
    System.out.println(i1==i2);
    System.out.println(i3==i4);
}

经理授课

  • 上述的程序最终输出的分别是falsetrue
  • 同样的操作为什么得到的不同的结果呢?除了值不同以外我真的看不出任何差别
  • 对!就是值的问题。因为值不同导致不同的结果。

缓存大佬IntegerCache

  • 在Integer中存在这样一个类IntegerCache,他的作用是将Integer的数据进行缓存。

image-20210514172531445

  • 我们查看下他的源码中对该类的解释。他将Integer的-128~127的数据进行缓存。
  • 换句话说,就是不在这个范围内的数据被视为冷数据。不做缓存处理。这里的缓存可以和String的常量池做一样的理解。
  • 所以上面的Integer i1=128;Integer i2=128 。实际上是在堆中的两个对象。因为128超出范围不做换出
  • Integer i3=127; Integer i4=127 在缓存范围内所以两个变量指向的是同一块地址。
  • 这也就解释了为什么一个false、一个true了。

小丽说

  • java中为什么要这么设计呢?
    • 答:这样设计肯定是为了节省内存。因为加入缓存所以避免了该范围内的数据重复的在堆中创建
  • 在java6以后可以通过XX:AutoBoxCacheMax=num 来设置IntegerCache区间的上限。
  • Integer i =100 会自动将100装箱成Integer对象的即会调用Integer.valueOf方法。
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}
  • 这段代码中就是Integer类中装箱的操作。里面通过IntegerCache实现我们本文的主题内容缓存范围。

  • 拆箱:自动拆箱就是包装类型转换成基本数据类型。自动拆箱调用了Integer.intValue(),

  • 装箱:自动装箱就是基本数据类型转换成包装类型。自动装箱过程调用了Integer.ValueOf(int),当int的范围是-128到127,是从Integer常量池中获取的,当超出这个范围是通过new产Integer对象.容易造成OOM