17

Java には 2 種類の等価性があることを常に理解しています。

  • value equality :.equals()メソッドを使用して、2 つのオブジェクトが null 以外のオブジェクト参照で等価関係を実装していることをテストします。
  • reference equality :==演算子を使用して、2 つのプリミティブ型またはメモリ位置が等しいことをテストします。

次のページでは、これらの言語の基礎について詳しく説明します。

nullこれらのリンクのいずれも明示的に指定していないのは、2 つのオブジェクト参照が値の等価性について比較された場合にどうなるかです。NullPointerExceptionをスローする必要があるという暗黙の前提がありますが、これはObjectUtils.equals()メソッドによって行われることではありません。これは、ベスト プラクティスのユーティリティ メソッドと見なされる可能性があります。

私が心配しているのは、Apache Commonsがバックドアによって Java に平等の第 3 の手段を効果的に導入したように見え、すでに混乱している状況がさらに複雑になった可能性があることです。値が等しいかどうかをテストしようとし、それが失敗すると参照が等しいかどうかのテストにフォールバックするため、私はこれを 3 番目の等価性の尺度と呼んでいます。Apache Commons の等価性テストは、値の等価性および参照の等価性と多くの類似点がありますが、明らかに異なります。

心配して、可能な限り使用を避けたいと思うのは正しいObjectUtils.equals()ですか?

ObjectUtils.equals()他の 2 つの平等の尺度の有用な結合を提供すると主張する議論はありますか?

選ばれた答え

この質問について意見が一致しているようには見えませんが、私は Bozho の意見を正しいとマークすることにしました。問題を隠ぺいしようとするのではなく、2 つの null オブジェクトの値が等しいかどうかを比較する根本的な原因に対処するフェイルファストコードを作成する必要があります。

4

3 に答える 3

10

これがのコードですObjectUtils.equals(..)

public static boolean equals(Object object1, Object object2) {
     if (object1 == object2) {
       return true;
     }
     if ((object1 == null) || (object2 == null)) {
       return false;
    }
    return object1.equals(object2);
}

ObjecUtilsのドキュメントには、渡されたオブジェクトがnullになる可能性があることが明記されています。

true次に、 2つのを比較した場合に返される必要があるかどうかについて説明しますnull。私の意見では-いいえ、理由は:

  • 2つのオブジェクトを比較するときは、後でそれらを使用して何かを行う可能性があります。これはにつながりますNullPointerException
  • 比較するために2つのsを渡すnullということは、おそらく何らかの問題が原因で、「実際の」オブジェクトではなく、どこかから取得したことを意味します。その場合、それらを単独で比較することは間違っています-プログラムフローはその前に停止する必要があります。
  • ここで使用しているカスタムライブラリには、-というメソッドがあります。これは、null比較でこのユーティリティequalOrBothNull()のメソッドとは異なります。equals
于 2010-01-25T15:36:33.950 に答える
5

ObjectUtils.equals() の使用を可能な限り避けたいと考えるのは正しいでしょうか?

いいえ。同等と見なす必要があるものは、要件によって異なります。また、NullPointerExceptions を処理することなく、2 つの null が等しく、null 以外のすべてが null と等しくないと見なすことは、非常に一般的な要件です (たとえば、setter から値変更イベントを発生させたい場合)。

実際には、それequals()は一般的にどのように機能するべきかであり、通常、その動作の半分が実装されています ( Object.equals()「For any non-null reference value x, x.equals(null)should return false.」の API ドキュメント)-逆に機能しないことこれは主に技術的な制限によるものです (言語は、よりシンプルにするために複数のディスパッチなしで設計されました)。

于 2010-01-25T15:43:51.713 に答える
1

これが心配な場合は、1)この方法を使用しない2)独自に作成してラップすることができます。

public class MyObjectUtils {
    public static boolean equals(Object obj1, Object obj2) {
        return obj1 != null && obj2 != null && ObjectUtils.equals(obj1, obj2);
    }
}

私には、nullをnullに等しくすることを許可するのは奇妙に思えますが、これは大きな問題ではないようです。ほとんどの場合、1つ以上のオブジェクトがnullの場合、アプリケーションが同等性テストを含むコードパスに入るとは思わないでしょう。

于 2010-01-25T15:38:41.357 に答える