次のスニペットに気づきました...
@Override
public boolean equals(Object otherObject) {
...
}
equals(Object x)
...メソッドはのように定義されfinal
ているため、列挙型には使用できませんEnum
。なんでそうなの?
equals(Object)
列挙型のオーバーライドが必要なユースケースは考えられません。この振る舞いの背後にある理由を知りたいだけです。
次のスニペットに気づきました...
@Override
public boolean equals(Object otherObject) {
...
}
equals(Object x)
...メソッドはのように定義されfinal
ているため、列挙型には使用できませんEnum
。なんでそうなの?
equals(Object)
列挙型のオーバーライドが必要なユースケースは考えられません。この振る舞いの背後にある理由を知りたいだけです。
それ以外return this == other
は直感に反し、驚き最小の原則に違反します。2つの列挙型定数はequal
、それらが同じオブジェクトであり、この動作をオーバーライドする機能がエラーを起こしやすい場合にのみ存在すると予想されます。
同じ理由が、、、、、、、およびにもhashCode()
当てはまります。clone()
compareTo(Object)
name()
ordinal()
getDeclaringClass()
JLSは、それを最終的なものにするという選択を動機付けるものではありませんが、ここで列挙型のコンテキストで等しいと述べています。スニペット:
のequalsメソッドは、引数を
Enum
呼び出して結果を返すだけの最終メソッドであり、ID比較を実行します。super.equals
のインスタンス(値)enum
が等しいことの意味について、強力で直感的な概念がすでに提供されています。メソッドのオーバーロードを許可するequals
と、その概念に違反し、予期しない動作やバグなどが発生します。
Javaの命名基準に準拠していないデータを処理する必要がある場合があります。このようなことができるといいでしょう:
public enum Channel
{
CallCenter("Call Center"),
BankInternal("Bank Internal"),
Branch("Branch");
private final String value;
Channel(String value)
{
this.value = value;
}
@Override
public String toString()
{
return value;
}
public static Channel valueOf(String value)
{
for (Channel c : Channel.values())
if (c.value.equals(value))
return c;
return null;
}
@Override
public boolean equals(Object other)
{
if (other instanceof String)
other = Channel.valueOf((String)other);
return super.equals(other);
}
}
「String」クラスは、対応するように変更する必要があります...
public boolean equals (Object object) {
if (object == this) return true;
if (object instanceof Enum)
object = object.toString();
if (object instanceof String) {
String s = (String)object;
// There was a time hole between first read of s.hashCode and second read
// if another thread does hashcode computing for incoming string object
if (count != s.count ||
(hashCode != 0 && s.hashCode != 0 && hashCode != s.hashCode))
return false;
return regionMatches(0, s, 0, count);
}
return false;
}
そのメソッドがfinalとして宣言されるのは、Java設計者がEnum.equals(Object)をオーバーライドするための考えられるユースケースを考えられなかったためです。そのため、そのようなオーバーライドは不可能です。
列挙型は、オーバーライドしたい最後のものであることを告白する必要がありますequals()
。
equals()
列挙型の最終的な理由は、Java==
が列挙型の比較を推奨しているためだと思います。列挙型の実装はequals()
単に列挙型を使用するため、equals()
オーバーライドを許可することは、他の開発者が予期しないことである、異なる動作を防止==
および防止することです。equals()