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);
}
}