重写正确的Java等于方法

我重写了Java类中的equals()方法,发现了一个我无法解释的难题。

标准equals()合同规定了这一点:

  • 它是自反的:对于任何参考值x,x.equals(x)应该返回true。
  • 它是对称的:对于任何参考值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才返回true。
  • 它是可传递的:对于任何引用值x,y和z,如果x.equals(y)返回true,并且y.equals(z)返回true,则x.equals(z)应该返回true。
  • 它是一致的:对于任何参考值x和y,x.equals(y)的多个调用始终返回true或始终返回false,前提是没有修改对象的等值比较中使用的信息。
  • 对于任何非空引用值x,x.equals(null)应该返回false。
  • 因此,标准的equals()方法可以这样构造:

    public boolean equals(Object other) {
        if (null == other) return false;
        if (this == other) return true;
        if (!(other instanceof MyClassName)) return false;
        MyClassName that = (MyClassName) other;
        return this.myMemberVariable.equals(that.name);
    }
    

    给定类Foo和类Bar extends Foo ,都使用成员变量String bazFoo内的标准equals()方法看起来像:

    public boolean equals(Object other) {
        if (null == other) return false;
        if (this == other) return true;
        if (!(other instanceof Foo)) return false;
        Foo that = (Foo) other;
        return this.baz.equals(that.name);
    }
    

    Bar内的标准equals()方法看起来像这样:

    public boolean equals(Object other) {
        if (null == other) return false;
        if (this == other) return true;
        if (!(other instanceof Bar)) return false;
        Barthat = (Bar) other;
        return this.baz.equals(that.name);
    }
    

    如果我有对象Foo foo = new Foo("Test");Bar bar = new Bar("Test"); ,并且我调用了foo.equals(bar) ,这将返回true 。 如果我通过equals()合约的对称子句调用bar.equals(foo) ,这是因为在Bar equals()中, (!(other instanceof Bar))true ,所以Barequal()方法返回false ,这是不正确的,它应该是true ,通过逻辑(两个对象String baz是彼此相等的),并通过对称子句,其中如果x.equals(y)y.equals(x)本质上是true

    我知道用于重写equals()getClass() vs instanceof参数,并且不需要这些参数中的另一个参数。

    这让我想起了我的实际问题。 在这种情况下,如何正确地重写遵循标准Java合约的equals()方法以实现相等性?


    根据你的问题

  • 如果他们有相同的baz Foo可以等于Bar
  • 如果他们有相同的baz Foo可以等于Foo
  • 如果他们有相同的baz Bar可以等于Bar
  • 这清楚地表明FooBar将具有与equals()完全相同的实现。 因此,你不应该重写它。

    如果您试图无视这一点并覆盖它,那么您会得出一个明显的结论:您无法将Bar下降到Foo ,但您可以将这两个参数都投射到Bar 。 只要你做到这一点,你会发现你可以简单使用.equals()Bar

    链接地址: http://www.djcxy.com/p/76221.html

    上一篇: Overriding Proper Java equals method

    下一篇: compareTo triggered at first add call on TreeSet in Java 1.7