読者です 読者をやめる 読者になる 読者になる

ジェネリクスとinstanceofについて

Java

例えば、ジェネリクスの抽象クラスを以下のように定義して、

public abstract class Base<T> {
    private int id;
    // ・・ getter setter
}

このクラスを以下の様に使いたかったとする。

public class Foo extends Base<Foo> {・・・}


親の Base には idが同じであれば同一。という equals のデフォルト実装を含めておこうとして

public abstract class Base<T> {
    // ・・・
    @Override public boolean equals(Object other) {
        if ( this == other ) return true;
        if ( !(other instanceof T)) return false;  // コンパイルエラー
            Base<T> cast = (Base<T>)other;
            return new EqualsBuilder().append(id, cast.getId()).isEquals();
	}
}

とすると、「other instanceof T」はコンパイルエラーになるのね。知らんかった。ジェネリクスの型情報はコンパイル時にのみ有効で、実行時の情報としては付加される訳ではないので当然と言えば当然か・・。


対応としては、こんなヘルパーメソッド作って、

    private boolean instanceOf(Object other) {
        return (other.getClass() == this.getClass());
    }

こんな風にしとけばよさそう。

    @Override public boolean equals(Object other) {
        if ( this == other ) return true;
        if ( !this.instanceOf(other)) return false;
            Base<T> cast = (Base<T>)other;
            return new EqualsBuilder().append(id, cast.getId()).isEquals();
	}