Java Integer 缓存机制的小坑点

Integer 是 Java 5 引入的新特性,该特性能节省内存和改善性能。同样被引入缓存机制的还有 Byte,Short,Long,Character,缓存范围都是在 [-128,127] (Character是在[0,127])之间。

但是有几点需要注意的是:
1. 对 Integer 对象引入了 IntegerCache 类,其他封装类型也有对应的 XxxCache。
2. 该缓存特性只有在 autoboxing 过程中使用,换言之,使用 constructor 创建的 Integer 并不能被缓存。
3. 因为缓存机制的存在,在缓存范围内的对象都来自同一个缓存。带来的副作用是使用“==”地址比较运算符比较两个看似不一样的对象,得到的是 true。网上其他文章的说法是因而可以使用 == 来比较直接比较两个对象的值。但我觉得这样理解容易造成偏差。Java 规范并没有约定 [-128,127] 的范围内 == 用作值比较,这只是一个副作用。
4. 只有 Integer 对象可以通过指定 JVM 启动参数来修改缓存上限。

-XX:AutoBoxCacheMax=size

所以说写代码的时候还是不要把==用作值比较。
 
老实说这个缓存特性带来的不一致性要是导致了什么BUG实在很难排查。当用了这个特性写了点什么之后,难保后来者不会产生迷惑。所以日常编码中还是尽量避开这个点。
 
简单到爆的实验代码:
简单地验证Java Integer缓存特性

import com.sun.istack.internal.NotNull;
 
/**
 * Created by Lawrence on 15/11/9.
 */
public class Main {
    public static void main(String[] argv){
        Integer int1 = 100;
        Integer int2 = 100;
 
        if(int1==int2){
            print("int1 is equal to int2");
        } else {
            print("int1 is not equal to int2");
        }
        // prints "int1 is equal to int2"
 
        Integer int3 = 2333;
        Integer int4 = 2333;
 
        if(int3==int4){
            print("int3 is equal to int4");
        } else {
            print("int3 is not equal to int4");
        }
        // prints "int3 is not equal to int4"
 
        Integer int5 = 100;
        Integer int6 = new Integer(100);
 
        if(int5==int6){
            print("int5 is equal to int6");
        } else {
            print("int5 is not equal to int6");
        }
        // prints "int5 is not equal to int6"
    }
 
    public static void print(String str){
        System.out.println(str);
    }
 
}