java中Integer与int比较浅谈

来源:互联网 发布:php 汉字长度 编辑:程序博客网 时间:2024/06/16 05:40
今天看到一个面试题
测试代码如下
public class test {
@Test
public void test(){
Integer a = 300 ;
Integer b = 300;
int c = 300;
System.out.println(a == b);
System.out.println(a == c);
Integer int1 = 100;
Integer int2 = 100;
System.out.println(int1 == int2);
}
}
输出结果
false
true
true

Process finished with exit code 0

300难道不等于300么。结果为什么会这样呢?
先反编译看一波
public class test {
public test() {
}

@Test
public void test() {
Integer a = Integer.valueOf(300);
Integer b = Integer.valueOf(300);
int c = 300;
System.out.println(a == b);
System.out.println(a.intValue() == c);
Integer int1 = Integer.valueOf("100");
Integer int2 = Integer.valueOf("100");
System.out.println(int1 == int2);
}
}

可见,通过 Integer a = 300;这种方法新建一个Integer实际上是调用 Integer.valueOf();的方法创建了一个Integer对象,那为什么a == b结果为false呢,我门继续看Integer.valueOf();的源码
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
这里冒出来一个IntegerCache类,我们继续看源码
IntegerCache 是 Integer的一个私有静态内部类,继续看
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() {}
}
从高亮部分代码我们可以看出
原来Integer把-128到127(可调)的整数都提前实例化了,但是为什么JDK要这么多此一举呢? 我们仔细想想, 淘宝的商品大多数都是100以内的价格, 一天后台服务器会new多少个这个的Integer, 用了IntegerCache,就减少了new的时间也就提升了效率。同时JDK还提供cache中high值得可配置,这无疑提高了灵活性,方便对JVM进行优化。

好了现在回来看出现3个问题
1.
Integer a = 300;
Integer b = 300;
System.out.println(a == b);
结果:false
原因 : 在创建a,b的时候实际上会调用Integer.valueOf();方法,在Integer.valueOf()方法中,范围在-128~127的都已经被提前实例化了,而我们这里的值为300,并没有被提前实例化,所以会new 一个新的Integer,而“==”是对地址的比较,a与b是分别new出来的,所有地址显然不一样,结果为false
2.
Integer int1 = 100;
Integer int2 = 100;
System.out.println(int1 == int2);
结果:true
有上面的基础这里就比较好理解了,因为Integer的-128~127都提前被实例化了,而100在这个范围之内,所以int1和int2实际指向内存同一块地址,故结果为true
3.
Integer a = 300 ;
int c = 300;
System.out.println(a == c);
结果 : false
这个从反编译的结果看来就很简单了,在jdk1.5后有了自动拆箱机制,a == c 实际上就是a.intValue() == c ,300 当然等于300所有结果为true