一、常见的回答:
equals比较的是对象的内容,而" =="比较的是对象的地址。
二、较为完整的回答
“默认情况下, 也就是从Object类中集成而来的equals方法与 == 是完全”等价的,也就是比较的是对象在内存中的地址。但是我们可以重写equals方法, 使其按照我们需要的方式进行比较,例如String类重写了equals方法,时其比较的时字符序列,而不再是内存地址。”
三、下面我们通过几个例子来深入探究"=="与equals方法
1、我们创建一个Person类,然后创建并实例化两个对象分别为personOne 、PersonTwo 。
‘=='运算符比较两个Person对象(personOne 与PersonTwo ),返回false, 这个是在意料之中的,因为personOne 与PersonTwo 是两个不同的对象, 因而地址也不会相同。程序的原意是,如果两个人的名字(name) 相等,就认为是同一个人,否则不是同一个人。然而, 尽管personOne 与PersonTwo 两个对象的名字相同,但是结果却事与愿违,equals 方法同样返回了false。
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public static void main(String[] args) {
Person personOne = new Person("Jennifer");
Person PersonTwo = new Person("Jennifer");
System.out.println(personOne == PersonTwo); //false
System.out.println(personOne.equals(PersonTwo)); //false
System.out.println(personOne.hashCode()); //366712642
System.out.println(PersonTwo.hashCode()); //1829164700
}
}
2、下面我们再来看一个String、StringBuffer 、StringBuilder 的例子。
public class SttringTest {
public static void main(String[] args) {
String strOne = new String("");
String strTwo = new String("");
System.out.println(strOne == strTwo); //false
System.out.println( strOne.equals(strTwo)); //true
StringBuffer bufferOne = new StringBuffer();
StringBuffer bufferTwo = new StringBuffer();
System.out.println(bufferOne == bufferTwo); //false
System.out.println(bufferOne.equals(bufferTwo)); //false
StringBuilder buliderOne = new StringBuilder();
StringBuilder buliderTwo = new StringBuilder();
System.out.println(buliderOne == buliderTwo); //false
System.out.println( buliderOne.equals(buliderTwo)); //false
}
}
3、如果对于这样的结果我们不明白为什么,那就是我们没有弄清楚equals方法到底比较的是什么。下面我们来看看String、StringBuffer 、StringBuilder中equals方法的源码:
4、 String中equals方法的源码
5、 StringBuffer 、StringBuilde中equals方法的源码
四、 问题总结:
从其根源来看,equals方法是在Object类中声明的,访问修饰符为public,而所有类(除Object类自 身外)都是Object的直接或间接子类,也就是 所有子类都继承了这个方法。在Object类中,equals方法实现如下:
public boolean equals(0bject obj) {}
从而可知, 在Object类中,equals方法与 == 运算符是完全等价的,而我们编写的Person 类继承了Object类中的equals方法,因此,Person 类中equals方法与 == 是等价的,也就是比较的是对象的地址,而非对象的内容。
对于String类,之所以该类可以比较对象的内容, 那是因为String类重写了equals方法,使该方法比较的是字符序列(也就是我们通常所说的内容)而非对象的地址。而对于StringBuilder与StringBuffer 两个类,与Person 类相同,没有重写equals方法。所有不同的对象,equals方法返回值为false。
五、 如何重写Person中的equals方法
@Override
public boolean equals(Object obj) {
if(obj instanceof Person) {
Person person = (Person)obj;
return name == person.name;
}
return false;
}
使用instanceof 来判断obj所指对象的类型,如果obj是Person类对象,就可以转换为Person对象,然后进行两个Person对象的名字比较,相等则返回true,否则返回false。