documentation
Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example, converting an int to an Integer, a double to a Double, and so on. If the conversion goes the other way, this is called unboxing.
自动装箱(拆箱也是)是 Java 编译器提供的原始类型和它的包装类之间转化的功能。
注意,自动装箱和拆箱是 Java 编译器的功能,并不是运行时的。
int 转 Integer:
Listli = new ArrayList<>(); for (int i = 1; i < 50; i += 2) li.add(i); // Java 编译器把上面的代码转换成了下面的样子 List li = new ArrayList<>(); for (int i = 1; i < 50; i += 2) li.add(Integer.valueOf(i));
反过来,Integer 转 int:
public static int sumEven(Listli) { int sum = 0; for (Integer i: li) if (i % 2 == 0) sum += i; return sum; } // 编译器把上面的代码转化成了下面的样子 public static int sumEven(List li) { int sum = 0; for (Integer i : li) if (i.intValue() % 2 == 0) sum += i.intValue(); return sum; }
Java 中 int 和I nteger 互转,原理是 Java 编译器帮你调用了包装类的 valueOf() 和 intValue() 两个方法。
Java Integer、int 与 new Integer()所有整型包装类对象之间的比较全部使用 equals 方法比较。
对于 Integer var = ? 在 -128 至 127 范围内的赋值,Integer 对象是在 IntegerCache.cache 产生,会复用已有对象,这个区间内的 Integer 值可以直接使用 == 进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,所以推荐使用 equals 方法进行判断。
- int 和 Integer 在进行比较的时候,Integer 会进行拆箱,转为 int 值与 int 进行比较。
- Integer 与 Integer 比较的时候,由于直接赋值的时候会进行自动的装箱。
IntegerCache 为 Integer 类的缓存类,默认缓存了 -128~127 的 Integer 值,如遇到 [-128,127] 范围的值需要转换为 Integer 时会直接从 IntegerCache 中获取,具体如以下源码:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
当大于这个范围的时候,直接 new Integer 来创建 Integer 对象。
new Integer(1) 和 Integer a = 1 ,前者创建对象,存储在堆中,而后者是从 IntegerCache 中获取的。那么 Integer a = 128, 直接通过 new Integer(128)创建对象,进行装箱。
public class Test {
public static void main(String[] args) {
Integer i = new Integer(128);
Integer i2 = 128; // 自动装箱
// == 比较对象的地址是不是相同
System.out.println(i == i2); // false
Integer i3 = new Integer(127);
Integer i4 = 127;
System.out.println(i3 == i4); // false
Integer i5 = 128;
Integer i6 = 128;
System.out.println(i5 == i6); // false
Integer i7 = 127;
Integer i8 = 127;
System.out.println(i7 == i8); // true
}
}
Integer.valueOf() new Integer()
当你需要产生一个整形的包装类的实例的时候(比如整数10),有两种方式:
第一种,使用构造函数 new 一个对象:
Integer i = new Integer(10);// 已过时,且标记为待删除。
第二种,使用静态工厂方法产生实例:
Integer i = Integer.valueOf(10);
当你用第一种方式时每次都会产生一个新的实例,而当你使用静态工厂方法时,不一定会产生一个新的实例,注意我说的是不一定,至少这里没有产生一个新的实例。
当你产生的数是 -128 到127时,不会 new 一个新的对象,超过这个范围时,同样是 new 一个新的对象。
为什么 Java 9 不建议使用 new Integer 了?java.lang.Integer @Deprecated(since = “9”)
@Contract(pure = true)
It is rarely appropriate to use this constructor. The static factory valueOf(int) is generally a better choice, as it is likely to yield significantly better space and time performance.
最后一句不说说了吗,有更好的空间和时间性能,你用new 也没事。
@HotSpotIntrinsicCandidate
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
上面是 valueOf, 当你传入小于 128 的值时,返回的是内置的缓存值,节省空间和效率。



