1. ==操作符
在Java中,==是用于比较两个变量或对象引用是否相等的操作符。它的行为取决于操作数的类型
1. 基本数据类型
对于基本数据类型(如int、float、boolean等),==用于比较它们的值是否相等。例如:
int a = 5;
int b = 5;
boolean result = (a == b); // true
在上面的例子中,a和b都是基本数据类型int,因此通过==比较它们的值,结果为true。
2. 对象引用类型
对于对象引用类型(如自定义类、字符串等),==用于比较两个对象引用是否指向同一个对象。例如:
String str1 = new String("hello");
String str2 = new String("hello");
boolean result = (str1 == str2); // false
在上面的例子中,str1和str2是两个不同的字符串对象,尽管它们的内容相同,但通过==比较它们的引用,结果为false,因为它们指向的是不同的对象。
注意:当引用对对象类型为字符串字面量时,当它们的值相同时,它们指向同一个对象(储存在常量池中)。例如:
String str1 = "hello";
String str2 = "hello";
boolean result = (str1 == str2); // true
小结:
- 对于基本数据类型来说,==比较的是它们的值是否相同
- 对于引用数据类型来说,==比较的是它们的内存地址是否相同(也即是它们的引用是否指向同一对象)
- 对于基本数据类型的值以及字符串字面量,Java 在编译期会进行优化,将它们直接存储在常量池中。因此,对于两个相同类型的字面量或者常量,它们的引用值是相同的,即它们指向的是同一个对象。
2. equals()方法
equals() 是 Java 中的一个方法,用于比较两个对象是否相等。它不能用于基本数据类型的比较,只能用于引用数据类型。下面对 equals() 进行详细解释:
1. 方法签名
在 Java 中,equals() 方法定义在 Object 类中,其方法签名为:
public boolean equals(Object obj)
该方法接收一个 Object 类型的参数 obj,并返回一个 boolean 类型的值,表示两个对象是否相等。
2. 默认实现
在 Object 类中,默认的 equals() 方法实现是比较两个对象的引用值是否相等。即判断两个对象是否指向内存中的同一个地址。如果两个对象的引用值相等,则返回 true,否则返回 false。
public boolean equals(Object obj) {
return (this == obj);
}
3. 自定义实现
在实际开发中,我们通常需要根据业务需求来重写 equals() 方法,以便比较对象的内容而不仅仅是引用值。重写 equals() 方法应满足以下条件:
- 对称性(Symmetry):对于任意非空对象 x 和 y,如果 x.equals(y) 返回 true,则 y.equals(x) 也应返回 true。
- 自反性(Reflexivity):对于任意非空对象 x,x.equals(x) 应返回 true。
- 传递性(Transitivity):对于任意非空对象 x、y 和 z,如果 x.equals(y) 返回 true,y.equals(z) 返回 true,则 x.equals(z) 也应返回 true。
- 一致性(Consistency):对于任意非空对象 x 和 y,如果两个对象的内容没有发生改变,多次调用 x.equals(y) 应返回相同的结果。
- 非空性(Non-nullity):对于任意非空对象 x,x.equals(null) 应返回 false。
在重写 equals() 方法时,通常需要先进行类型检查,避免与其他类型的对象进行比较。然后再根据具体业务逻辑来比较对象的各个属性是否相等,例如比较字符串、数字、集合等。
4. 示例代码
public class Person {
private String name;
private int age;
// 构造方法、getter和setter省略
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Person person = (Person) obj;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
在上述示例中,我们重写了 equals() 方法,比较了 name 和 age 两个属性的值是否相等,并使用了 Objects.equals() 方法来比较字符串类型的属性。同时,我们还重写了 hashCode() 方法,以保持 equals() 和 hashCode() 的一致性。
小结:
- 未重写equals方法:当某个类没有重写equals方法时,equals具有和==操作符相同的效果,比较的是它们的内存地址是否相同
- 重写equals方法:当某个类重写了equals方法时,通常比较的是对象的内容是否相同
顺便提一嘴,一般面试问 == 和 equals 的区别时,答上面内容中的小结部分即可。