深入探究"=="与equals方法的区别

一、常见的回答:

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。

发布了62 篇原创文章 · 获赞 21 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/lsy_666/article/details/104507246