Java中Integer的true或者false问题是一个非常常见的问题,也就是==和equals的关系,那你真的懂什么是
equals
吗?你可能会想:不就是比较地址和比较值嘛,小学生都会,那你怕是对equals有什么误解。本文参考:Java3y
你真的懂equals()吗?
之前也写过类似的博文,让我以为我已经彻底弄懂了这个问题,但是当我真正看到这道题时,我还是做错了。
可以先过一遍我之前的文章基本类型与包装类判断是否相等问题
public class Main {
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
Long h = 2L;
System.out.println(c==d);
System.out.println(e==f);
System.out.println(c==(a+b));
System.out.println(c.equals(a+b));
System.out.println(g==(a+b));
System.out.println(g.equals(a+b));
System.out.println(g.equals(a+h));
}
}
先自己思考一下吧!!!
在解这道题之前,相信很多人都已经知道了,在Java中会有一个Integer缓存池,缓存的大小是:-128~127
/**
* Cache to support the object identity semantics of autoboxing for values between
* -128 and 127 (inclusive) as required by JLS.
*/
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() {}
}
也就是说>127的和<-128的都会new一个新的Integer:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
那么前四个答案显而易见了,关键是后面后面三个答案是啥???
简单解释一下这道题:
使用==
的情况:
- 如果比较Integer变量,默认比较的是地址值。
- Java的Integer维护了从
-128~127
的缓存池
- 如果比较的某一边有操作表达式(例如a+b),那么比较的是具体数值
使用equals()
的情况:
-
无论是Integer还是Long中的
equals()
默认比较的是数值。 -
Long的
equals()
方法,JDK的默认实现:会判断是否是Long类型 -
注意自动拆箱,自动装箱问题。
这里需要特别注意一下Long中的equals方法,我们可以点进Long.class看看
显而易见,Long的equals()
方法,JDK的默认实现:会判断是否是Long类型。(Float、Double的equals()方法其实也是这样判断的)
反编译一下看看:
import java.io.PrintStream;
public class Main_1 {
public static void main(String[] paramArrayOfString) {
Integer localInteger1 = Integer.valueOf(1);
Integer localInteger2 = Integer.valueOf(2);
Integer localInteger3 = Integer.valueOf(3);
Integer localInteger4 = Integer.valueOf(3);
Integer localInteger5 = Integer.valueOf(321);
Integer localInteger6 = Integer.valueOf(321);
Long localLong = Long.valueOf(3L);
// 缓存池
System.out.println(localInteger3 == localInteger4);
// 超出缓存池范围
System.out.println(localInteger5 == localInteger6);
// 存在a+b数值表达式,比较的是数值
System.out.println(localInteger3.intValue() == localInteger1.intValue() + localInteger2.intValue());
// equals比较的是数值
System.out.println(localInteger3.equals(Integer.valueOf(localInteger1.intValue() + localInteger2.intValue())));
// 存在a+b数值表达式,比较的是数值
System.out.println(localLong.longValue() == localInteger1.intValue() + localInteger2.intValue());
// Long的equals()先判断传递进来的是不是Long类型,而a+b自动装箱的是Integer类型
System.out.println(localLong.equals(Integer.valueOf(localInteger1.intValue() + localInteger2.intValue())));
// ... 最后一句在这里漏掉了,大家应该可以推断出来
}
}
答案:
- true
- false
- true
- true
- true
- false
- true