11.7 方法equals

本书前面介绍了两种检查两个值是否相等的方式:运算符 == 和方法 equals。这两种方式都可用于对象,但它们的含义不同。

  • 运算符 == 检查两个对象是否相同(identical),即指的是否是同一个对象。

  • 方法 equals 检查两个对象是否相等(equivalent),即它们的值是否相同。

相同的定义是固定不变的,因此运算符 == 所做的事情始终相同;但相等的定义随对象而异,因此对象可定义自己的方法 equals。请看下面的变量:

  1. Time time1 = new Time(9, 30, 0.0);
  2. Time time2 = time1;
  3. Time time3 = new Time(9, 30, 0.0);

图 11-2 所示的状态图显示了这些变量及其值。

{%}

图 11-2:显示三个 Time 变量的状态图

赋值运算符复制引用,因此 time1time2 指向同一个对象。因为它们相同,所以 time1 == time2true

然而,time1time3 指向不同的对象。因为它们不同,所以 time1 == time3false

默认情况下,方法 equals 的行为与 == 相同。就 Time 对象而言,这可能不是我们所希望的。例如,time1time3 表示的时间相同,因此,应将它们视为相等。

我们可提供一个实现这种相等定义的 equals 方法:

  1. public boolean equals(Time that) {
  2. return this.hour == that.hour
  3. && this.minute == that.minute
  4. && this.second == that.second;
  5. }

equals 是一个实例方法,因此,它使用 this 来引用当前对象,且其定义中没有包含关键词 static。我们可以像下面这样来调用这个 equals 方法:

  1. time1.equals(time3);

在这个 equals 方法中,this 指的是对象 time1,而 that 指的是对象 time3。因为这两个对象的实例变量相等,所以结果为 true

很多对象采用了类似的相等定义,即如果两个对象的实例变量相等,那么这两个对象就相等。然而,也可用其他的方式定义相等。