Integer源码分析与自动装箱的缓存机制
一、自动装箱实现原理
- 基本类型与包装器类型
8种基本类型均有对应的包装器类型 - 装箱与拆箱场景
- 初始化
- 容器
- 返回值
- 运算
- 实现原理
public class TestBoxing {
public static void main(String[] args) {
Integer i = 1;
int j = i;
System.out.println(i);
System.out.println(j);
}
}
反编译后:
Compiled from "TestBoxing.java"
public class javase.TestBoxing {
public javase.TestBoxing();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_1
1: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
4: astore_1
5: aload_1
6: invokevirtual #3 // Method java/lang/Integer.intValue:()I
9: istore_2
10: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
13: aload_1
14: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
17: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
20: iload_2
21: invokevirtual #6 // Method java/io/PrintStream.println:(I)V
24: return
}
即:
- 装箱:valueOf() 返回值对应的包装器对象
- 拆箱:intValue() 返回包装器具体的值
- 注意点
包装器为对象,比较需要用equals方法
二、奇怪的现象
public class TestInteger {
public static void main(String[] args) {
Integer i1 = 10;
Integer i2 = 10;
Integer i3 = 1000;
Integer i4 = 1000;
System.out.println(i1 == i2);
System.out.println(i3 == i4);
}
}
输出:
true
false
三、源码分析
- valueOf:正常对应-128到127的,直接使用cache中已创建好的对象,减小频繁创建对象开销
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
- IntegerCache:创建一定范围的cache
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
cache内比较可以用==,超出范围必须用eauqls方法