java中equals和==
在java中,我们常常会使用到equals方法和==判断数值和对象是否相等,为了不混淆这两个的用法,特意拿出来单独写一篇博客记录,面试也是经常问的问题。
区别
- equals是判断两个变量或者实例指向同一个内存空间的值是不是相同
- 而==是判断两个变量或者实例是不是指向同一个内存空间
equals方法的重写
我们在了解一个方法的同时,查看源码是一个好的习惯,首先equals是Object类下的一个方法,如下
public class Object {
// 省略
public boolean equals(Object obj) {
return (this == obj);
}
}
可以看到,其实equals的实现代码十分简单,也就是返回了一个this==obj,用于比较自身和传入的Object对象的值是否相等。
那么我们为什么要说equals和==的区别呢?这俩不是一样的吗?
这里要提到的就是equals的重写,大部分的类使用equals的时候,都要继承Object类并且重写它的equals方法!
不信我们来看一下String类的源码里,equals方法是如何实现的:
public final class String{
/**
* Compares this string to the specified object. The result is {@code
* true} if and only if the argument is not {@code null} and is a {@code
* String} object that represents the same sequence of characters as this
* object.
*
* @param anObject
* The object to compare this {@code String} against
*
* @return {@code true} if the given object represents a {@code String}
* equivalent to this string, {@code false} otherwise
*
* @see #compareTo(String)
* @see #equalsIgnoreCase(String)
*/
public boolean equals(Object anObject) {
if (this == anObject) {
return true; // 判断是否是同一个对象,如果是那么肯定他们的值也相等,则不执行后续代码
}
if (anObject instanceof String) { // 判断对象是否也是String类型
String anotherString = (String)anObject; // 强转为String类型
int n = value.length; // 这里的value其实是对应的String存储值的char[] value,之前的博客提到过
if (n == anotherString.value.length) { // 首先判断两个String类型的value长度是否一致
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) { // 来个循环,遍历比较每一个字符值是否相等
if (v1[i] != v2[i])
return false; // 有一个字符不相等则返回false
i++;
}
return true; // 全部字符相等则返回true
}
}
return false; // 假如上面代码没有返回,则默认返回false
}
}
上面每一行代码细细品读,就能发现,其实String类的equals方法和Object类的equal方法还是有很大差别的吧!在String类重写的equals方法中,首先进行的是对象内存地址的判断,接着才是对象值的判断!所以我们大体上可以说,String类的equals方法其实是对两个对象的值的判断!而在Object类中,==和equals其实没多大区别!
当然理论上讲完了,实践才是最能检验真理的!
看下面的代码:
public static void main(String[] args) {
String s1 = new String("123");
String s2 = new String("123");
System.out.println(s1==s2); // false
System.out.println(s1.equals(s2)); // true
}
可以看到上面==和equals的比较结果是不一样的,因为我们是new的两个String,所以在内存中会分配两块空间,==之前也提到过,是比较对象的内存地址是否相同,所以直接返回了false。而equals方法会进入到刚刚那里,首先进行对象的判断,这个时候因为不是同一个对象,所以继续判断长度是否一致,长度一致后再循环判断每一个字符是否相等,发现全部相等,因此输出了true。
那么除了String以外,几乎绝大部分的类都是自己重写了equals方法,基本上都是比较对象的值是否相等。像HashMap、ArrayList等等类,感兴趣的可以自己去阅读源码。