陷阱 - 過載而不是覆蓋

請考慮以下示例:

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();
    }
}

此程式碼不會按預期執行。問題是 Personequalshashcode 方法不會覆蓋 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 註釋新增到方法宣告時,編譯器將檢查該方法是否覆蓋(或實現)在超類或介面中宣告的方法。所以在上面的例子中,編譯器會給我們兩個編譯錯誤,這應該足以提醒我們錯誤。