什么叫自动装箱和拆箱
简单来说:
自动装箱:就是自动将基础类型转换为包装器类型
自动拆箱:就是自动将包装器类型转换为基础类型
// 自动装箱
Integer num1 = 400;
// 自动拆箱
int num2 = num1;
根据概念,那么8种基础类型都支持自动装箱和拆箱,他们都各自对应一种包装类型:
image.png如何自动装箱&&拆箱
我们可以通过反编译class文件,得到编译器生成的字节码
源代码:
public class TestBox {
public static void main(String[] args) {
// 自动装箱
Integer num1 = 400;
// 自动拆箱
int num2 = num1;
}
}
通过命令行javap -c TestBox.class
得到对应的字节码:
public class TestBox {
public TestBox();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: sipush 400
3: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
6: astore_1
7: aload_1
8: invokevirtual #3 // Method java/lang/Integer.intValue:()I
11: istore_2
12: return
}
通过字节码可以看到,编译器帮我们自动完成了拆箱和装箱的过程。
-
可以看到,装箱过程其实就是通过调用
Integer.valueOf()
方法:public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
最后一句
return new Integer(i)
就比较简单了,直接返回包装类对象。我们主要看一下这个if
判断,当i
小于127,大于-128时, 这时候是返回的缓存:static { .... 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; }
系统帮我们缓存从-128——127的包装类对象,当我们去使用的时候,可以直接使用。我们可以通过程序验证一下:
public class TestBox { public static void main(String[] args) { // 自动装箱 Integer num1 = 400; // 自动拆箱 int num2 = num1; Integer n1 = 100; Integer n2 = 100; Integer n3 = 200; Integer n4 = 200; System.out.println(n1==n2); // true System.out.println(n3==n4); // false } }
输出结果:
true false
可以看到,因为100<127,所以
n1
和n2
两个两个对象其实指向的是同一个对象,而n3
和n4
指向的是不同的包装类对象 -
我们在说一下拆箱过程,编译器自动为我们调用了
Integer.intValue()
方法进行拆箱public int intValue() { return value; }
拆箱就很简单了,直接返回
int
值
总结
- 需要知道什么叫拆箱&&装箱
- 需要知道什么时候进行拆箱&&装箱
- 因为装箱会创建包装类对象,所以频繁的装箱会消耗内存,影响性能。所以能避免就避免
- equals(Object o) 因为原equals方法中的参数类型是封装类型,所传入的参数类型(a)是原始数据类型,所以会自动对其装箱,反之,会对其进行拆箱
网友评论