==
和 equals
方法在比较对象时的区别
1. ==
运算符
- 基本数据类型:对于基本数据类型(如
int
、char
、double
等),==
比较的是它们的值是否相等。例如:
int a = 5;
int b = 5;
System.out.println(a == b); // 输出: true
- 引用数据类型:对于引用数据类型(如类、数组等),
==
比较的是两个引用是否指向同一个对象,即它们在内存中的地址是否相同。例如:
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1 == str2); // 输出: false,因为 str1 和 str2 指向不同的对象
2. equals
方法
equals
方法是Object
类的一个实例方法,在Object
类中,equals
方法的默认实现和==
一样,比较的是两个对象的引用是否相等。Object
类中equals
方法的定义如下:
public boolean equals(Object obj) {
return (this == obj);
}
- 许多类(如
String
、Integer
等)重写了equals
方法,使其用于比较对象的内容是否相等。例如:
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1.equals(str2)); // 输出: true,因为 String 类重写了 equals 方法,比较的是字符串内容
在自定义类中正确重写 equals
方法
在自定义类中重写 equals
方法时,需要遵循以下几个原则:
- 自反性:对于任何非空引用值
x
,x.equals(x)
应该返回true
。 - 对称性:对于任何非空引用值
x
和y
,当且仅当y.equals(x)
返回true
时,x.equals(y)
才应该返回true
。 - 传递性:对于任何非空引用值
x
、y
和z
,如果x.equals(y)
返回true
,并且y.equals(z)
返回true
,那么x.equals(z)
也应该返回true
。 - 一致性:对于任何非空引用值
x
和y
,多次调用x.equals(y)
始终返回true
或始终返回false
,前提是对象上equals
比较中所用的信息没有被修改。 - 非空性:对于任何非空引用值
x
,x.equals(null)
应该返回false
。
以下是一个自定义类重写 equals
方法的示例:
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
// 1. 检查是否为同一个引用
if (this == obj) {
return true;
}
// 2. 检查是否为 null
if (obj == null) {
return false;
}
// 3. 检查是否为同一类型
if (getClass() != obj.getClass()) {
return false;
}
// 4. 强制类型转换
Person other = (Person) obj;
// 5. 比较对象的属性
return age == other.age && (name == null ? other.name == null : name.equals(other.name));
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Alice", 20);
Person p2 = new Person("Alice", 20);
System.out.println(p1.equals(p2)); // 输出: true
}
}
在上述示例中,Person
类重写了 equals
方法,首先检查两个对象是否为同一个引用,然后检查对象是否为 null
,接着检查对象是否为同一类型,最后比较对象的属性是否相等。