没有自动拆装箱
int a = 1;
Integer b = new Integer(a);
int c = b.intValue();
自动装箱/拆箱
int a = 1;
Integer b = a; // 自动装箱
int c = b; // 自动拆箱
字节码反编译
Compiled from "Test.java"
public class demo.Test {
public demo.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: iconst_1
1: istore_1
2: iload_1
3: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
6: astore_2
7: aload_2
8: invokevirtual #3 // Method java/lang/Integer.intValue:()I
11: istore_3
12: return
}
自动装箱的本质就是调用包装类的Xxx.valueOf(),如Integer.valueOf()
自动拆箱的本质就是调用保证类的Xxx.xxxValue,如Integer.intValue()
Integer 缓存机制
- 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);
}
private static class IntegerCache {
static final int low = -128;
static final int high = 127;
}
Integer缓存了-128~127的整数
Integer a = 1;
Integer b = 1;
System.out.println(a == b); // true
注意
- 所有基本类型包装类的都重写了Object.equals()
例如:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
equals()都判断了对象真正类型,如果类型不匹配,比较直接返回false,此处是比较容易忽略的地方。
Integer a = 1;
Integer b = 2;
Long c = 3L;
// 打印false,因为a+b自动装箱为Integer,Long.equals(Integer) return false
System.out.println(c.equals(a + b));