Java:タイプセーフなequals
問題
equalsは便利な仕組みなのだが、このメソッドはタイプセーフにできない。そのために、間違ったオブジェクトと比較してしまい、常にfalseが返されるというバグの原因になる。例えば、
public static class Foo {
int value;
@Override
public boolean equals(Object o) {
if (!(o instanceof Foo)) return false;
return ((Foo)o).value == this.value;
}
}
public static class Bar {
}
.......
Foo foo = new Foo();
Bar bar = new Bar();
foo.equals(bar);
などとやってしまう。これは常にfalseになる。
方策1
実行時にエラーにする。
public static class Foo {
int value;
public boolean equals(Object o) {
if (!(o instanceof Foo)) throw new RuntimeException("Unexpected object");
return ((Foo)o).value == this.value;
}
}
方策2
当然以下のようには書けない。
public static class Foo {
int value;
@Override
public boolean equals(Foo o) { // <-- 引数型をObject以外にはできない
if (!(o instanceof Foo)) return false;
return ((Foo)o).value == this.value;
}
}
仕方が無いので、別メソッドを作成する。タイプセーフにするにはこれしかないようだ。
public static class Foo {
int value;
@Override
public boolean equals(Object o) {
if (!(o instanceof Foo)) return false;
return ((Foo)o).value == this.value;
}
public boolean eq(Foo o) {
return equals(o);
}
}