Java-学习日记(100 == 100为true,1000 == 1000却为false?)

Integer底层设计

100 == 100为true,1000 == 1000却为false?

之前也写过String的==与equals的注意点,这次写下Integer的底层设计,不妨先运行下下面代码:

Integer a = 1000, b = 1000;  
System.out.println(a == b);//1
Integer c = 100, d = 100;  
System.out.println(c == d);//2

基本知识:我们知道,如果两个引用指向同一个对象,用 == 表示它们是相等的。如果两个引用指向不同的对象,用 == 表示它们是不相等的,即使它们的内容相同。

这里就涉及到Integer底层的IntegerCache.java,它缓存了从 - 128 到 127 之间的所有的整数对象。

具体实现就是:当所有的小整数在内部缓存,然后当我们声明类似——

Integer c = 100;

实际做的是

Integer i = Integer.valueOf(100);

而内部valueof实现

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

如果值的范围在 - 128 到 127 之间,它就从高速缓存返回实例,C与D的引用其实都是指向同一对象,所以相同,而不再这个值得a,b就不从高速缓存放回实例,所以不指向同一对象。

综上所述:java中,像String,Integer这些不要用==进行比较,因为比较的是引用(基本数据类型除外),应该使用equals,这也符合sonarlint规范。

下面给出高速缓存的魅力吧!

public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {

    Class cache = Integer.class.getDeclaredClasses()[0]; //1
    Field myCache = cache.getDeclaredField("cache"); //2
    myCache.setAccessible(true);//3

    Integer[] newCache = (Integer[]) myCache.get(cache); //4
    newCache[132] = newCache[133]; //5

    int a = 2;
    int b = a + a;
    System.out.printf("%d + %d = %d", a, a, b); // 2  +  2= 5;
}
原文地址:https://www.cnblogs.com/meditation5201314/p/13610366.html