前言
遇到过好多次比较大小和是否相等的,对equal和==了解一些,但是不是很全面,今天就整理一下,梳理一下,没事了就常看一下。
1.首先说“==”
我们知道所有的对象都拥有标志(内存地址)和状态(数据),“==”就是用来比较两个对象的内存地址的,内存地址相同,则为同一个对象,system.out.println(a == b)就为ture。
2.equals
equals的情况就有点复杂,复杂就复杂在子类对Object类中的equals()方法进行重写了。重写的理由就是为了方便我们进行数据的比较。
超类Object中有equals()方法,该源码为:
public boolean equals(Object obj) {
return (this == obj);
}
但是在String、Math、Integer、Double……等类中是重写了equals方法。
在String中的源码为
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
在这段代码if (v1[i++] != v2[j++])return false;可以看出String的equals()方法是进行内容的比较,而不是地址的比较。
至于其它的封装类也差不多,但是我还想对Integer在说点。
先看代码
Integer a = 127;
Integer b = 127;
Integer c = 128;
Integer d = 128;
System.out.println(a.equals(b));//①
System.out.println(c.equals(d));//②
System.out.println(a==b);//③
System.out.println(c==d);//④
结果是
true //①
true //②
true //③
false //④
对于①和②很好理解,因为Integer对equals进行重写了吗,比较的是值的大小,自然就相等,为true。
③和④怎么就一个true,一个为false呢,这里也涉及到了另一个概念,自动装箱。Integer a = Integer.valueOf(127);Integer b = Integer.valueOf(127);
设计到valueOf函数了,看一下源代码吧
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
对于-128到127之间的数会进行缓存,在一次定义变量时会从缓存中取,不用new新对象,在-128到127之外的数,是会进行new一个新的对象。所以③为ture,④为false了。
在出一个题吧
Integer a = 288;
int d = 288;
System.out.println(d == a);
这个结果为true,这个涉及到了Integer的拆箱,基本类型是存储在栈中,包装类型是存储在堆中,当int和Integer在一起时,Integer会自动拆箱,变成int类型,而双等于永远是比较对象/基本类型存储的引用的值,所以这个例子结果为true。
在 java 中进行比较,我们需要根据比较的类型来选择合适的比较方式:
1) 对象域,使用 equals 方法 。
2) 类型安全的枚举,使用 equals 或== 。
3) 可能为 null 的对象域 : 使用 == 和 equals 。
4) 数组域 : 使用 Arrays.equals 。
5)除 float 和 double 外的原始数据类型 : 使用 == 。
6) float 类型: 使用 Float.foatToIntBits 转换成 int 类型,然后使用==。
7) double 类型: 使用 Double.doubleToLongBit 转换成 long 类型,然后使用==。