LoginSignup
0
0

More than 5 years have passed since last update.

Item 40: Consistently use the Override annotation

Posted at

40.一貫してOverrideアノテーションを使うべし

Javaライブラリはいくつかのアノテーションを提供してるが、多くのプログラマにとって、@Override が一番重要だろう。
一貫して@Override を使用していれば、バグが起こりにくくなる。
以下のbigramを模したクラスを例に見ていく(バグあり)。

package tryAny.effectiveJava;

import java.util.HashSet;
import java.util.Set;

//Can you spot the bug?
public class Bigram {
    private final char first;
    private final char second;

    public Bigram(char first, char second) {
        this.first = first;
        this.second = second;
    }

    public boolean equals(Bigram b) {
        return b.first == first && b.second == second;
    }

    public int hashCode() {
        return 31 * first + second;
    }

    public static void main(String[] args) {
        Set<Bigram> s = new HashSet<>();
        for (int i = 0; i < 10; i++)
            for (char ch = 'a'; ch <= 'z'; ch++)
                s.add(new Bigram(ch, ch));
        System.out.println(s.size());
    }
}

このプログラムは26を出力すると思いきや、260を出力する。
原因はequalsをOverrideするつもりがOverloadしてしまっていることにある。Object.equalsの引数はObject型であり、シグニチャが違う。
こういった誤りを防ぐために、Overrideするメソッドには@Overrideをつける。そうすると以下のコードはコンパイルエラーとなる。

@Override public boolean equals(Bigram b) {
    return b.first == first && b.second == second;
}

正しくは以下のようになる。

@Override
public boolean equals(Object o) {
    if (!(o instanceof Bigram))
        return false;
    Bigram b = (Bigram) o;
    return b.first == first && b.second == second;
}

このようなことから、親クラスのメソッドをOverrideするときは@Overrideをつけるべきである
これには一つ例外があって、具象クラスにおいて、親の抽象メソッドをOverrideするときは、そもそもOverrideしないとコンパイルエラーが出るので、@Overrideの記述の必要はない(記述による害もない)。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0