这是道蛮有意思的面试题。
不废话,看题:
public class Main {
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1 == i2);
System.out.println(i3 == i4);
}
}
输出是多少?
运行下试试:
这是道极好的考察基础的面试题。如果我是面试官,我并不 care 你能不能答对。接下来我会问下面两个知识点
- == 和 equals 的区别
- Integer 自动装箱过程
== 和 equals 的区别
这个问题都问烂了,简单说一下。
==:判断是否是同一个引用,或两个基本类型是否相等
equals:类覆写的一个方法,用于判断两个对象是否 equal,判断规则由覆写的方法决定
Integer 自动装箱过程
整型自动装箱会调用 Integer 的 valueof 方法,返回一个 Integer 对象,该方法有多个重载。
//Interger 的 valueof 方法
public static Integer valueOf(String s, int radix) throws NumberFormatException {
return Integer.valueOf(parseInt(s,radix));
}
public static Integer valueOf(String s) throws NumberFormatException {
return Integer.valueOf(parseInt(s, 10));
}
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
这里就可以解释下为什么 “200 != 200” 了。
Integer i3 = 200; -> Integer.valueof(200)
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
看看 IntegerCache
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
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;
}
private IntegerCache() {}
}
通过代码可以看见 IntegerCache.low 到 IntegerCache.high 之间的数做了缓存,在这个区间的数的包装类型始终是同一个引用,不在这个区间就会重新分配内存。所有 i1 == i2, i3 != i4。
jdk 这么做,我猜应该是这些较小的数,通常情况下使用比较频繁,干脆缓存起来,免得反复分配回收内存。