这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战
写在前面
平常开发中,大家都用什么方法来判断两个值是否相等,脱口而出的是equals,先给大家个结论,那就是不建议大家a.equals(b)去判断是否相等,看完本篇文章就知道了,大家都知道的是判断对象是否为空 是否相同都是拿== 来判断,那么不是对象呢。
当值是null的情况
1、a.equals(b) , a 是null
null.equals("abc") → 抛出 NullPointerException 异常
这种意料之内,null是不能干任何事的,否则都会报空指针的
2、a.equals(b), a不是null, b是null
"abc".equals(null) → 返回 false
可以看到 这次不报错了。而且结果确实为false。
3、a和b都为null时,我们看下(肯定也报空指针)
null.equals(null) → 抛出 NullPointerException 异常
也经常拿Objects来判断 。Objects.equals(a, b)比较时, 若a 和 b 都是null, 则返回 true, 如果a 和 b 其中一个是null, 另一个不是null, 则返回false。注意:不会抛出空指针异常。
Objects.equals(null, "abc") → 返回 false
Objects.equals("abc",null) → 返回 false
Objects.equals(null, null) → 返回 true
接下来再看当是空字符串的情况
值是空字符串
1、a 和 b 如果都是空值字符串:""
"".equals("") → 返回 true
1、如果a和b其中有一个不是空值字符串,则都会返回false;
"abc".equals("") → 返回 false
"".equals("abc") → 返回 false
再看Objects
Objects.equals("abc", "") → 返回 false
Objects.equals("","abc") → 返回 false
Objects.equals("","") → 返回 true
所以说当值是空字符串的时候 这样判断是没有问题的。
我们看下源码,为什么会出现这种差异
究其源码
先来看Objec根类 equals
public class Object {
private static native void registerNatives();
static {
registerNatives();
}
//首先this不可能去拿null去判断 所以null去equals行不通
//obj传进来的可以为空,因为是拿 == 去判断的
//归根到底还是==去判断
public boolean equals(Object obj) {
return (this == obj);
}
...
}
接下来再看Objecs中的equals
public final class Objects {
private Objects() {
throw new AssertionError("No java.util.Objects instances for you!");
}
/**
* Returns {@code true} if the arguments are equal to each other
* and {@code false} otherwise.
* Consequently, if both arguments are {@code null}, {@code true}
* is returned and if exactly one argument is {@code null}, {@code
* false} is returned. Otherwise, equality is determined by using
* the {@link Object#equals equals} method of the first
* argument.
*
* @param a an object
* @param b an object to be compared with {@code a} for equality\
* @return {@code true} if the arguments are equal to each other\
* and {@code false} otherwise
* @see Object#equals(Object)
*/
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
...
}
-
首先,进行了对象地址的判断,如果是真,则不再继续判断。
-
如果不相等,后面的表达式的意思是,先判断a不为空,然后根据上面的知识点,就不会再出现空指针。
-
所以,如果都是null,在第一个判断上就为true了。如果不为空,地址不同,就重要的是判断a.equals(b)。
总结
当Object.equals 第一值要判空,或者直接用Objects.equals去判断
OK。今天我们就学习到这里,分享一点小细节,积少成多。我们下期再见 加油!