Java 重写了超类Equals和HashCode,并认为应该对子类执行同样的操作
我有一个带有2个变量(Java 重写了超类Equals和HashCode,并认为应该对子类执行同样的操作,java,equals,hashcode,Java,Equals,Hashcode,我有一个带有2个变量(inta)(intb)的超类,还有一个子类,它通过使用子类中现有的改进方法覆盖2个超类方法来扩展超类的功能。作为我的子类的一部分,我现在有了一个新的int(intc),它是一个唯一的id(UUID) 我理解用equals方法很难保持平等 我是否可以覆盖超类equals和hashCode方法以显示相等,并根据上述情况对子类equals和hashCode方法执行相同操作 我最初重写了超类中的equals和hashCode方法。如果由于子类中的额外实例变量(int c)也应该对子
inta
)(intb
)的超类,还有一个子类,它通过使用子类中现有的改进方法覆盖2个超类方法来扩展超类的功能。作为我的子类的一部分,我现在有了一个新的int
(intc
),它是一个唯一的id(UUID)
我理解用equals
方法很难保持平等
我是否可以覆盖超类equals
和hashCode
方法以显示相等,并根据上述情况对子类equals
和hashCode
方法执行相同操作
我最初重写了超类中的equals
和hashCode
方法。如果由于子类中的额外实例变量(int c
)也应该对子类执行此操作。我知道应该有一个hashCode
方法来显示这一点,我读到如果haschCode
被更改,那么子类的equals
方法必须更改吗
我真的不知道该怎么做才是最好的
我想知道我的超类equals
和hashCode
方法是否可以显示相等关系?是否允许子类与我的超类equals
和hashCode
重写方法一起显示inta
、intb
和intc
的相等比较,以及子类的hashCode
方法更新以显示int
sa
的唯一hashCode>,b
和c
我正在考虑比较超类equals
方法中的int
sa
和b
并更新这两个变量的hashcode,以及equals
方法中的int
sa
、b
和c
更新这三个变量的hashcode。只是超类中的intc
是唯一的
非常感谢这里的任何建议,因为我相信忽略和不处理子类equals
和hashCode
方法中的int c
可能是不可能的
提前感谢基本上,您有两种可能的选择:
c
。根据a
和b
定义超类的相等性,不要在子类中重写它
a
和b
)和子类(基于a
、b
和c
)中以不同的方式定义相等性
请注意,在这种情况下,在子类中重写equals()
和hashcode
是不够的-在实现超类的equals()
方法时,还需要一个特殊的技巧,请参阅中关于canEquals()
方法的部分
你的问题的关键是你是否希望你的超类的一个实例和你的子类的一个实例能够相等地进行比较 如果是这样,请不要重写
equals()
和hashCode()
方法。您甚至可以在超类中将它们设置为final
如果不是,则每个类的equals()
方法应使用getClass()
,而不是instanceof
检查equals()
的参数类型。例如,在超类中:
if ((obj == null) || (!getClass().equals(obj.getClass()))
return false;
/* Compare a and b. */
...
在子类中:
if (!super.equals(obj))
return false;
/* Compare c. */
...
如果哈希代码基于a
和b
字段,则可能不必重写hashCode()
方法,但如果在子类的实现中考虑c
,则类作为键的工作可能会更好。也就是说,它会将具有不同c
值的键放入不同的bucket中,而不是将具有相同a
和b
的所有实例聚集在同一个hash bucket中。++to Jordan Bently
对于您编写的每个类,通常最好重写equals()
、toString()
和hashCode()
。实际上,这并不总是有意义的。要不是你在做什么,我会这么做的。是的,您可以在子类中更改实现
最好使用
@Override
标记每个被重写的方法,以帮助向要重写的开发人员提供文档。这提示他们,如果不是您的超类,您至少正在重写java.lang.Object
。这取决于您的超类。假设您的超类是A
,而B扩展了A
,那么这可能会发生
a.等于(a)
b.等于(b)
(真)?b、 hash==a.hash:hash不重要a.equals(b)
(真)?b、 hash==a.hash:hash不重要b.等于(a)
A
和B
应该如何关联?有两种选择:
A
和B
是完全不同的,因此A.equals(B)
或B.equals(A)
是始终为false。这是最安全的方法。您需要在equals中测试a.getClass()==b.getClass()
以确保a
和b
是完全相同的类型。例如,Eclipse IDE在generate equals()和hashCode()中默认自动生成此类等式A
和B
可以比较,但不能在B
中覆盖它以保持equals()
和hashCode()的契约。
这是由于equals的对称契约(A.equals(B)==B.equals(A)
)而强制的为了确定hashCode和equals的行为,您需要
class Foo { int a, b; }
class Bar extends Foo { int c;}
Foo x = new Foo(a,b);
Bar y = new Bar(a,b,c);
x.equals(y); //returns false
y.equals(x); //returns true