12

一般的な質問: Java でデフォルト メソッドのオーバーライドを実装する場合、既に実装されているメソッドを単純に利用することと、独立したロジックを equals メソッドに書き込むequalsことについて、どのような懸念が必要ですか? 別の質問で誰かcompareToが言及しているのに気付きました。これらの一貫性のない結果が理想的な機能である理由は何ですか?foo.equals((String)null)String.compareTo((String)null)NullPointerException

サンプルequals方法:

@Override
public boolean equals(Object obj) {
    if (obj != null && obj instanceof MyClass) {
        MyClass msg = (MyClass)obj;
        return this.compareTo(msg) == 0;
    }
    return false;
}

編集:Comparable のドキュメントからの引用

クラス C の自然順序付けは、e1.compareTo(e2) == 0 がクラス C のすべての e1 および e2 について e1.equals(e2) と同じブール値を持つ場合にのみ、equals と一致すると言われます。 null はどのクラスのインスタンスでもなく、e.equals(null) が false を返す場合でも、e.compareTo(null) は NullPointerException をスローする必要があります。

編集:

さらに検討した結果、比較可能なドキュメントには次のようにも記載されていることに注意してください。

実装者は、すべての x と y に対して sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) を保証する必要があります。(これは、y.compareTo(x) が例外をスローする場合、x.compareTo(y) が例外をスローする必要があることを意味します。)

したがって、null.compareTo(x)明らかにNPEx.compareTo(null)スローするため、NPE もスローする必要があります。一方、等しい場合は、必ずしもそうではありません。私は NPE の適切な取り扱いにかなり関心があるので、これは比較的重要なことだと思います。

4

2 に答える 2

6

との違いはequals()、が指定されたクラスのインスタンスの自然な順序を識別するために使用される場合に、2 つのオブジェクトが互いに等しいかどうかをチェックするcompareTo()ことだけです。また、メソッドにはメソッドとのコントラクトがありますが、ありません。equals()compareTo()equals()hashCode()compareTo()

JavaDocによると:

null はどのクラスのインスタンスでもないことに注意してください。e.equals(null) が false を返しても、e.compareTo(null) は NullPointerException をスローする必要があります。

(x.compareTo(y)==0) == (x.equals(y)) にすることを強くお勧めしますが、厳密には必須ではありません。一般的に言えば、 Comparable インターフェースを実装し、この条件に違反するクラスは、この事実を明確に示す必要があります。推奨される言語は、「注: このクラスには、equals と矛盾する自然な順序付けがあります。」

compareTo()メソッド内でメソッド ロジックを自由に再利用できますが、 へのすべてのコントラクトと、メソッドの JavaDoc からequals()のコントラクトを念頭に置いてください。それらが互いに競合しない場合は、先に進みます。equals()hashCode()compareTo()

契約の履行がより重要なポイントだと思います。

于 2013-05-29T15:04:30.347 に答える