最近在学习Java程序设计,学到“==”和Object类中的equals()方法的时候有点混乱。
上结论!!!
“==”:用于判断二者是否同一,即二者的引用变量是否指向同一个对象。
Object.equals():用于判断二者是否相等,即二者的状态和对象类型是否相同。
书上的一个例子说明了“==”与equals()方法的区别。
以下是例子代码(摘自《Java核心技术》卷一):
Employee.java
package equals;
import java.time.*;
import java.util.Objects;
/*
* 一个{@Employee}代表一个雇员。
* 其中构造函数参数:
* @param name表示姓名
* @param salary表示薪水
* @param year年
* @param month月
* @param day日
*/
public class Employee {
private String name;
private double salary;
private LocalDate hireDay;
public Employee(String name, double salary, int year, int month, int day) {
this.name = name;
this.salary = salary;
hireDay = LocalDate.of(year, month, day);
}
// 获得该雇员姓名
public String getName() {
return name;
}
// 获得该雇员薪水
public double getSalary() {
return salary;
}
// 获得该雇员聘用日期
public LocalDate getHireday() {
return hireDay;
}
/*
* 提升该雇员奖金
*
* @param byPercent表示提升薪水的份额(如:5表示5%)
*/
public void raiseSalary(double byPercent) {
double raise = salary * byPercent / 100;
salary += raise;
}
/*
* {@equals}用于比较该对象与另一个对象是否相等
*
* @param otherObject表示对象
*
* @return 返回一个布尔值true或false
*/
public boolean equals(Object otherObject) {
if (this == otherObject)
return true;
if (otherObject == null)
return false;
if (getClass() != otherObject.getClass())
return false;
Employee other = (Employee) otherObject;
return Objects.equals(name, other.name) && salary == other.salary && Objects.equals(hireDay, other.hireDay);
}
//返回该对象的hash码
public int hashCode() {
return Objects.hash(name, salary, hireDay);
}
//输出该对象的相关信息
public String toString() {
return getClass() + "[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]";
}
}
Manager.java
package equals;
/*
* 一个{@Manager}表示一个经理,一个经理也是一个雇员(继承{@Employee}类)
* 此类增多了一个私有域bonus表示奖金
*/
public class Manager extends Employee {
private double bonus;
public Manager(String name, double salary, int year, int month, int day) {
super(name, salary, year, month, day);
bonus = 0;
}
//获得该经理的薪水
public double getSalary() {
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
//设该经理的奖金数
public void setBonus(double bonus) {
this.bonus += bonus;
}
/*
* 比较该对象是否跟另一个对象相等
*
* @param otherObject表示对象
*
* @return 返回一个布尔值true或false
*/
public boolean equals(Object otherObject) {
if (!super.equals(otherObject))
return false;
Manager other = (Manager) otherObject;
return bonus == other.bonus;
}
//输出该对象的信息
public String toString() {
return super.toString() + "[bonus=" + bonus + "]";
}
}
测试代码 EqualsTest.java
package equals;
/*
* This program demonstrates the equals method.
* @version 1.12 2012-01-26
* @author Cay Horstman
*/
public class EqualsTest {
public static void main(String[] args) {
//构造四个Employee对象
Employee alice1 = new Employee("Alice Adams", 75000, 1987, 12, 15);
Employee alice2 = alice1;
Employee alice3 = new Employee("Alice Adams", 75000, 1987, 12, 15);
Employee bob = new Employee("Bob Brandson", 50000, 1989, 10, 1);
System.out.println("alice1 == alice2:" + (alice1 == alice2));
System.out.println("alice1 == alice3:" + (alice1 == alice3));
System.out.println("alice1.equals(alice3):" + alice1.equals(alice3));
System.out.println("alice1.equals(bob)" + alice1.equals(bob));
System.out.println("bob.toString:" + bob.toString());
//构造两个Manager对象
Manager carl = new Manager("Carl Cracker", 80000, 1987, 12, 15);
Manager boss = new Manager("Carl Cracker", 80000, 1987, 12, 15);
boss.setBonus(5000);//设boss的奖金为5000
System.out.println("boss.toString:" + boss);
System.out.println("carl.equals(boss):" + carl.equals(boss));
System.out.println("alice1.hashCode():" + alice1.hashCode());
System.out.println("alice3.hashCode():" + alice3.hashCode());
System.out.println("bob.hashCode()" + bob.hashCode());
System.out.println("carl.hashCode():" + carl.hashCode());
}
}
执行程序,运行结果是这样的:
我们先分析alice。alice2变量引用的是alice1,所以alice1 == alice2的结果为true。
而alice3是新构造的Employee类型,其状态(值)虽然与alice1相等,但alice1与alice3并不一是同一个引用(脑内浮现千千万万个白绝),所以alice1 == alice3的结果为false,alice1.equals(alice3)的结果为true。
再看carl和boss,程序给boss设置了奖金5000,而没有给carl设置奖金,carl和boss的奖金是不一致的,所以carl.equals(boss)的结果为false。
从输出的hash码中可以发现alice1和alice3的hash码是一样的,而carl和boss的hash码不相同,那意味着如果两个引用变量的对象类型和状态(值)都相等,其hash码也相等。
在实际应用中,如果要判断两个变量是否引用同一个对象的话,应该使用“==”,避免使用Object类的equals()方法。
【错误的地方希望大家帮忙指正,谢谢!】