《Java》:Integer对象和 ==、equals分析
今天看到Integer的一个小知识点,比较有意思。
我们都知道
Integer i = 3;
等价于
Integer i = Integer.valueOf(3);
问题:下面这段代码应该输出什么呢?
Integer i =3;
Integer j =3;
System.out.println(i==j);
答案是: true。
在解释之前,再看如下的程序
public class Test {
public static void main(String[] args){
Integer c = 3;
Integer d = 3;
Integer c2 = new Integer(3);
Integer d2 = new Integer(3);
System.out.println(c == d);
System.out.println(c2 == d2);
System.out.println(c == c2);
}
}
我们都知道 用 ==来比较两个对象是否相同,比较是引用,即 == 两边是否指向同一个对象,如果是同一个对象的引用,则返回true,否则返回false。因此,上面的结果也就比较好理解。
从上面的程序结果可以看出:
Integer c = 3;
Integer d = 3;
中的 c、d是指向同一个对象。这是为什么呢?在进行解释之前,先看下面这个例子。
public class Test1 {
public static void main(String[] args){
Integer e = 127;
Integer f = 127;
Integer g = 128;
Integer h = 128;
System.out.println(e == f);
System.out.println(g == h);
}
}
从结果可以看出,程序中的e、f也是指向同一个对象,而g、h不是指向同一个对象。
Integer i = XXX;
Integer j = XXX;
i、j是否指向同一对象和值XXX有密切关系。
产生上面这种现象的原因是什么呢??
这是由于在Integer的源码实现中,Integer 把-128-127 之间的每个值都建立了一个对应的Integer 对象放入了一个数组中,这里的数组类似于缓存,提前给你准备好这个范围内的对象。由于Integer 是不可变类,因此这些缓存的Integer 对象可以安全的重复使用。
Integer i = XXX ,就是Integer i = Interger.valueOf(XXX), 首先判断XXX 是否在-128-127 之间,如果是直接return 已经存在的对象,否则就只能new 一个了。
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就是一个缓冲类,其代码如下:
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
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);
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k cache[k] = new Integer(j++);
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
看了这个类的代码,相信你也就明白为什么当出现Integer i = XXX;
Integer j = XXX;代码且XXX的值在-128~127范围内时,i、j就是指向的是同一个对象了。
而equals方法就比较简单,是比较两个对象的值是否相等,如果相等,则返回true,否则返回false.
Integer类中的equals方法的代码如下:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
Integer/int类型的 ==
上面是两个Integer类型变量的==研究。下面是关于两个变量中一个是Integer类型,一个是int类型的==的研究。
package com.wrh.test;
public class Test2 {
public static void main(String[] args){
Integer a = 1;
int a2 = 1;
Integer a3 = new Integer(1);
System.out.println(a==a2);
System.out.println(a3==a2);
System.out.println(a.equals(a2));
}
}
结论:Integer对象和int变量是可以比较的,只是Integer对象先完成拆箱工作。