Java中的Integer.valueoOf(String)的诡异行为
Sun 22 December 2013 by XiaomengZhao今天看到stackoverflow中有个一非常有意思的问题,特把它翻译出来收藏。StackOverflow原帖地址为http://stackoverflow.com/questions/20877086/confusion-in-method-integer-valueofstring/ .
问题是这样的:
System.out.println(Integer.valueOf("127")==Integer.valueOf("127"));
System.out.println(Integer.valueOf("128")==Integer.valueOf("128"));
System.out.println(Integer.parseInt("128")==Integer.valueOf("128"));
输出的却是:
true
false
true
问题解决:
Interger类的valueOf
返回的是Integer
对象。默认情况下,如果参数在-128到127之间,则返回缓存中的对象,否则返回new Integer(int)。它在JDK5中具体实现如下:
private static class IntegerCache
{
private IntegerCache(){}
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
static
{
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}
public static Integer valueOf(int i)
{
final int offset = 128;
if (i >= -128 && i <= 127) // must cache
{
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
而在JDK6中它的具体实现:
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
也就是说我们可以设置系统属性 java.lang.Integer.IntegerCache.high
修改缓冲区上限,默认为127。那么如何修改这个上限呢?我们可以在启动程序时,我们需要给虚拟机加参数:
java -Djava.lang.Integer.IntegerCache.high=300 Main
这样也就解决了为什么第1条语句返回true了,因为他们的数值小于等于127,所以都是引用IntegerCache的同一个值为127的Integer对象,所以相等。而128由于大于127,没有了缓存机制,则引用不同的对象,所以不等。如果想判断两个Integer对象的值相不相等,请使用equals()
函数。
但是第三条语句System.out.println(Integer.parseInt("128")==Integer.valueOf("128"));
为什么相等呢?这是因为parseInt()
返回基本类型int
,在需要比较时,右边的Integer对象发生拆箱操作也返回基本类型int
,基本类型int进行比较,返回true。
References: