Java 常用类 03. Java 整数缓冲区
2021-12-16 本文已影响0人
yjtuuige
问题:
- 同样为数字 100 为什么结果有时返回
false
,有时返回true
,而用同样的方法再使用 200,却带来不同的结果。具体看代码及运行结果。
public class Main {
public static void main(String[] args) {
Integer n1=new Integer(100);
Integer n2=new Integer(100);
System.out.println(n1==n2);
Integer n3=100; // 自动装箱
Integer n4=100;
System.out.println(n3==n4);
Integer n5=200; // 自动装箱
Integer n6=200;
System.out.println(n5==n6);
}
}
- 结果:

原因:
- Java 预先创建了 256 个常用的整数包装类型对象。(类似字符串中的字符串池,只是这个池中已经有内容了)
- 在实际应用当中,对已创建的对象进行复用。
- 缓存区数组 [-128, 127]
分析:
- n1、n2 比较:属于两个对象,存储的地址不同,所以不相等返回 false。
- n3、n4 和 n5、n6 通过自动装箱创建,但比较结果不同
- 上面的代码可以写成:
public class Main {
public static void main(String[] args) {
Integer n1=new Integer(100);
Integer n2=new Integer(100);
System.out.println(n1==n2);
// 自动装箱,Integer.valueOf() 为隐藏代码
Integer n3=Integer.valueOf(100);
Integer n4=Integer.valueOf(100);
System.out.println(n3==n4);
// 自动装箱,Integer.valueOf() 为隐藏代码
Integer n5=Integer.valueOf(200);
Integer n6=Integer.valueOf(200);
System.out.println(n5==n6);
}
}
- 查看
valueOf()
源码:
@IntrinsicCandidate
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
- 发现:
valueOf(int i)
方法中的参数值在IntegerCache.low
与IntegerCache.high
之间时,会返回数组IntegerCache.cache[]
中的值。 - 查看
IntegerCache
类的源码:
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer[] cache;
static Integer[] archivedCache;
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
h = Math.max(parseInt(integerCacheHighPropValue), 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(h, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
// Load IntegerCache.archivedCache from archive, if possible
CDS.initializeFromArchive(IntegerCache.class);
int size = (high - low) + 1;
// Use the archived cache if it exists and is large enough
if (archivedCache == null || size > archivedCache.length) {
Integer[] c = new Integer[size];
int j = low;
for(int i = 0; i < c.length; i++) {
c[i] = new Integer(j++);
}
archivedCache = c;
}
cache = archivedCache;
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
- 从源码中可以看出
IntegerCache.low==-128
、IntegerCache.high==127
,同时可以看出,数组cache[]
大小为 256,存放的元素为{-128,-127,…,126,127}
。 - 因为 100 在
IntegerCache.low~IntegerCache.high
之间,所以返回的是数组cache[]
中的元素,所以在比较 n3 与 n4 时,两者指向的为同一元素,同一地址,而 200 并不在上面的范围中,所以返回new Interger(200)
。 - 相当于
public class Main{
public static void main(String[] args) {
Integer a[]={100};
Integer n3=a[0];
Integer n4=a[0];
System.out.println(n3==n4);
Integer n5=new Integer(200);
Integer n6=new Integer(200);
System.out.println(n5==n6);
}
}