面试题:问以下代码输出的结果是多少?
public class IntegerTest {
@Test
public void test() {
Integer a = 127;
Integer b = 127;
System.out.println(String.format("运行结果:%s", a == b));
a = 128;
b = 128;
System.out.println(String.format("运行结果:%s", a == b));
}
}
如果不仔细看上面的代码,那么我想很多人都会很快的说出运行的结果。但如果仔细查看代码,却不知道上述代码中的要考察的相关知识时,我想也不一定能准确说出正确的运行结果。那么下面我们看一下上述代码的运行结果:
运行结果:true
运行结果:false
你猜对了吗?为什么上面的代码显示的结果居然是不一样的呢?下面我们详细分析一下上述代码主要考察的知识点。
上述代码主要考察的是Java中Integer包装类对象的知识。但在这里有一个很隐性的知识点,也就IntegerCache对象。也就是因为这个对象的存在才导致上述代码中运行的结果不一致的。下面我们来了解一下Java中IntegerCache对象的知识。
IntegerCache
IntegerCache类实际上是Java中Integer中的缓存类,目的是节省内存消耗,提高程序性能。因为我们知道,在Java中每创建一个对象,都会将对象存储在堆内存中。而当堆内存中的对象存储非常多时,就有可能造成内存泄漏。而在我们日常的项目开发中我们使有用Integer类型的频率非常高。使用频率高创建对象也就越多,堆内存中的对象也就越多,所以也就会可能发生上述中的内存溢出等问题。所以Java为了解决上述问题。于是设计了IntegerCache类,看名字就知道IntegerCache是个缓存类,既然是缓存类,目的就是可以将相关的数据缓存下来,这里的数据指的就是Integer类的值。也就是上述代码中的等于右边的数值。那既然IntegerCache类可以缓存数字,为什么上述代码中的结果不一样呢?这个原因就是IntegerCache类有一个缓存范围。IntegerCache类缓存的数据范围为是-128到127之间。所以上述代码中前两行代码中输出结果为true(127在IntegerCache类缓存的数据范围内,于是将127缓存起来,当程序在使用这个127数字时,因为缓存中已经有了,于是直接使用缓存中的127,所以结果为true),而后二行代码输出的结果为false(超出IntegerCache类的缓存范围,于是不能缓存,所以创建了新的对象,既然是新的对象结果显然是false)。
为了验证我们上述我说的,我们看一下IntegerCache类的底层实现。下面为源码:
/**
* Cache to support the object identity semantics of autoboxing for values between
* -128 and 127 (inclusive) as required by JLS.
*
* The cache is initialized on first usage. The size of the cache
* may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
* During VM initialization, java.lang.Integer.IntegerCache.high property
* may be set and saved in the private system properties in the
* sun.misc.VM class.
*/
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() {}
}
看源码中的注释我们知道,我们可以通过Jvm中的AutoBoxCacheMax参数来重新设置IntegerCache类的缓存范围。并且我们知道IntegerCache类使用了Integer cache[] 数据缓存数值。
这就是上述面试题中所要考察的相关知识,实际上除IntegerCache类之外,在Java中还提供了ByteCache、ShortCache、LongCache、CharacterCache等缓存对象,其中前三个缓存对象的缓存范围都是-128 到 127。而CharacterCache缓存对象则是0到127。这就是Java中IntegerCache类相关的知识,如有考虑不周,或者输写有误的地方,欢迎留言,谢谢。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。