本文主要探讨以下三种方式生成一个Integer对象的区别
1.Integer num= 130;
2.Integer num = new Integer(12);
3.Integer num = Integer.valueOf(12);
方式1:直接将一个int赋值给一个Integer对象,这个时候130这个int值会被自动装箱成一个Integer对象。我们采用如下代码来验证到底是不是包装成了一个Integer对象
public class IntegerAutoBox {
public static void main(String[] args){
Integer num = 130;
}
}
我们通过javap -c 命令查看编译后的内容如下
我们可以看到,在main方法里我们调用Integer num = 130;的时候,会调用Integer.valueOf()这个静态方法来生成一个Integer对象,这个就是自动装箱。
接下来我们就来看看通过这三种方式生成一个Integer对象的区别。
首先,我们来看看自动装箱的方式,我们运行如下代码
public static void main(String[] args){
Integer num1 = 10;
Integer num2 = 10;
System.out.println("num1 == num2 ? " + (num1 == num2));
Integer num3 = 128;
Integer num4 = 128;
System.out.println("num3 == num4 ? " + (num3 == num4));
}
运行后,我们会发现赋值为10的时候,打印出来的是true,赋值为128的时候打印出来的是false,这是为什么呢?上面我们已经提到了,采用这种方式赋值,最终调用的是Integer.valueOf()来生成的一个Integer对象,那么我们就来看看Integer.valueOf()的源码
public static Integer valueOf(int var0) {
return var0 >= -128 && var0 <= Integer.IntegerCache.high ? Integer.IntegerCache.cache[var0 + 128] : new Integer(var0);
}
我们可以看到,当这个int值大于等于-128小于Integer.IntegerCache.high的时候,会从Integer.IntegerCache.cache这个数组(对象池)里面去取一个Integer对象,否则的话会调用new Integer()方法来生成一个新的Integer对象。那么Integer.IntegerCache.high的值是多少呢,我们来看看Integer.IntegerCache源码
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer[] cache;
private IntegerCache() {
}
static {
int var0 = 127;
String var1 = VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
int var2;
if (var1 != null) {
try {
var2 = Integer.parseInt(var1);
var2 = Math.max(var2, 127);
var0 = Math.min(var2, 2147483518);
} catch (NumberFormatException var4) {
;
}
}
high = var0;
cache = new Integer[high - -128 + 1];
var2 = -128;
for(int var3 = 0; var3 < cache.length; ++var3) {
cache[var3] = new Integer(var2++);
}
assert high >= 127;
}
}
我们可以看到在静态代码块里面执行了high = var0(127);并且采用for循环将cache[]数据进行了初始化,里面的对象就是-128 ~ +127这个区间段的所有对象。所以说,当我们通过自动装箱的方式来生成一个Integer对象的时候,如果我们传的值在-128 ~ +127的话,都会从Integer.IntegerCache.cache这个数据里面去取,所以说通过自动装箱方式生成Integer对象的时候,赋值在-128 ~ +127之间的时候,生成的多个对象都是同一个,这就是所谓的“享元模式”。而赋值超出这个范围的时候,会通过new Integer()来生成对象,故而生成的多个Integer对象不是同一个。
通过new Integer方式来生成Integer对象,不管传的值是多少,都会创建新的,所以通过new Integer()方式生成的Integer对象始终不是同一个。
通过Integer.valueOf()来生成的对象,在-128 ~ +127这个范围内,生成的是同一个对象,否则生成的对象不一样
以上就是关于三种方式创建Integer对象的区别。