通过下述例子描述
package com.brx.equals;
public class Student {
private String name;
public Student(String name) {
this.name=name;
}
@Override
public String toString() {
return super.toString();
}
}
package com.brx.equals;
public class Test {
public static void main(String[] args) {
Student s1=new Student("张三");
Student s2=new Student("张三");
System.out.println(s1==s2); // false
System.out.println(s1.equals(s2)); // false
}
}
"s1==s2"
对于基本数据类型比较的是数值;对于引用数据类型比较的是地址。
比较的是s1里的内容是否等于s2里的内容。因为s1,s2是两个不同的对象,存储的是不同的地址,所以为false。
要想判断两个对象是否相等,不能通过比较两个对象的引用是否相等,这是永远都得不到相等的结果的,因为两个对象的引用永远不会相等,所以正确的比较方法是直接比较这两个对象,比较这两个对象的实质是不是一样的,即这两个对象里面的内容是不是相同的,通过比较这两个对象的属性值是否相同而决定这两个对象是否相等。
Object类提供了一个equals()方法来比较两个对象的内容是否相同,因此我们可以采用这个方法去比较两个对象是否在逻辑上“相等”。如:c1.equals(c2);这里是调用从Object类继承下来的equals()方法,通过查阅API文档得到Object类里的equals方法的定义如下:
public boolean equals(Object obj) {
return (this==obj);
}
在Object这个类里面提供的
Equals()方法默认的实现是比较当前对象的引用和你要比较的那个引用它们指向的是否是同一个对象,即和“s1==s2”这种写法是一样的,
“s1.equals(s2)”与“s1==s2”是完全等价的。
因此直接使用继承下来的equals()方法也是无法直接比较两个对象的内容是否相同的,为此,我们必须
重写equals()方法,改变这个方法默认的实现。
还有一个问题
package com.brx.equals;
public class Test {
public static void main(String[] args) {
Student s1=new Student("张三");
Student s2=new Student("张三");
//System.out.println(s1==s2);
// 原来Object的equals方法比较的是==
System.out.println(s1.equals(s2)); //false
// 为什么字符串.equals(字符串)会出现相等的情况?
System.out.println(s1.toString().equals(s2.toString()));//true
}
}
在
String类里面重写equals()方法的实现方法为:用当前的这个字符串对象和指定的字符串对象比较,指定的字符串对象不能为空并且这个对象的字符序列和当前这个字符串对象的
字符串序列一样,如果这些条件都满足,那么这两个字符串对象就是相等的。
因此这里的s2已经满足了条件,所以打印出来的结果是true。
重写equals方法实现package com.brx.equals;
public class Student {
private String name;
public Student(String name) {
this.name=name;
}
@Override
public String toString() {
return "姓名"+name;
}
@Override
public boolean equals(Object arg0) {
if(arg0==null){
return false;
}else{
/**
* 这里是重写从Object类继承下来的equals()方法,改变这个方法默认的实现,
* 通过我们自己定义的实现来判断决定两个对象在逻辑上是否相等。
* 这里我们定义如果两个学生的name相同,
* 那么我们就认为这两个学生是同一个学生,即这两个学生是“相等”的。
*/
//这里使用了关键字instanceof——判断一个对象是否是这个类的实例。
//但是关键字instanceof不能判断这个对象是否是本类对象还是其子类对象
//因此使用类的字节码进行判断
/*if(!(arg0 instanceof Student)){
return false;
}*/
// 标准写法,通过类的字节码判断是否是同一个类的对象。
if(arg0.getClass()!=this.getClass()){
return false;
}
if(arg0==this){
return true;
}
Student s=(Student)arg0;
return s.name.equals(this.name);
}
}
}
测试
package com.brx.equals;
public class Test {
public static void main(String[] args) {
Student s1=new Student("张三");
Student s2=new Student("张三");
//System.out.println(s1==s2);
// 原来Object的equals方法比较的是==
System.out.println(s1.equals(s2)); //true
// 为什么字符串.equals(字符串)会出现相等的情况?
System.out.println(s1.toString().equals(s2.toString()));//true
}
}