陷阱 - 重载而不是覆盖
请考虑以下示例:
public final class Person {
private final String firstName;
private final String lastName;
public Person(String firstName, String lastName) {
this.firstName = (firstName == null) ? "" : firstName;
this.lastName = (lastName == null) ? "" : lastName;
}
public boolean equals(String other) {
if (!(other instanceof Person)) {
return false;
}
Person p = (Person) other;
return firstName.equals(p.firstName) &&
lastName.equals(p.lastName);
}
public int hashcode() {
return firstName.hashCode() + 31 * lastName.hashCode();
}
}
此代码不会按预期运行。问题是 Person
的 equals
和 hashcode
方法不会覆盖 Object
定义的标准方法。
equals
方法签名错误。它应该被声明为equals(Object)
而不是equals(String)
。hashcode
方法名称错误。它应该是hashCode()
(注意大写字母 C )。
这些错误意味着我们已经声明意外重载,如果在多态上下文中使用 Person
,则不会使用这些错误。
但是,有一种简单的方法可以解决这个问题(从 Java 5 开始)。每当你使用 @Override
注解打算你的方法是一个覆盖:
Version >= Java SE 5
public final class Person {
...
@Override
public boolean equals(String other) {
....
}
@Override
public hashcode() {
....
}
}
当我们将 @Override
注释添加到方法声明时,编译器将检查该方法是否覆盖(或实现)在超类或接口中声明的方法。所以在上面的例子中,编译器会给我们两个编译错误,这应该足以提醒我们错误。