关于Java的自动装箱拆箱
Java为8大基本数据类型提供了对应的包装类
基本数据类型 | 包装类(引用类型) |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
下面以int对应的Integer来举例
装箱(基本类型 -> 引用类型): int -> Integer
拆箱(引用类型 -> 基本类型): Integer -> int
自动装箱拆箱的简单代码
public class Test {
public static void main(String[] args) {
//自动装箱
Integer i = 100;
//自动拆箱
int a = i;
}
}
查看class文件
D:\代码\Design_pattern\src\main\java>javap -c Test.class
Compiled from "Test.java"
public class Test {
public Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: bipush 100
2: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: astore_1
6: aload_1
7: invokevirtual #3 // Method java/lang/Integer.intValue:()I
10: istore_2
11: return
}
通过class文件可以看出: 自动装箱调用Integer.valueOf()方法,自动拆箱调用Number接口中的intValue()方法
分析Integer源码
Integer中有个静态内部类IntegerCache
它是一个Integer的缓冲池,在静态块中默认将 [-128,127] 的Integer缓存到cache数组中
private static class IntegerCache {
//下限写死了 -128
static final int low = -128;
static final int high;
static final Integer cache[];
static {
//默认上限127 可以通过JVM参数往127以上进行修改
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);
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
}
}
high = h;
//创建对象放入缓冲池
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
使用JVM参数修改缓冲池上限
//修改上限为200
//-XX:AutoBoxCacheMax=200
System.out.println(Integer.valueOf(200) == Integer.valueOf(200));//true
当自动装箱调用valueOf()时,如果值在[-128,higt]范围中就会去缓冲池数组返回包装类,否则通过new创建包装类对象
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
当自动拆箱调用intValue()时,直接返回包装类的字段value
public int intValue() {
return value;
}