我们有一个 OO 代码库,在很多情况下hashcode()
根本equals()
不起作用,主要是因为以下原因:
除非您愿意放弃面向对象抽象的好处,否则无法在保留 equals 契约的同时扩展可实例化类并添加值组件。
这是 Joshua Bloch 的“Effective Java”中的一句话,在 Artima 的一篇很棒的文章中有更多关于这个主题的内容:
http://www.artima.com/lejava/articles/equality.html
我们对此非常满意,这不是这个问题的意义所在。
问题是:看到在某些情况下您无法满足equals()
合同是事实,那么自动生成hashcode()
和equals()
抛出 UnsupportedOperationException 的干净方法是什么?
注释会起作用吗?我正在考虑类似的事情@NotNull
:每次@NotNull
违反合同都会自动引发异常,除了用@NotNull
.
这很方便,因为它是 8 个字符(“@NotNull”),而不是不断重复相同的验证/抛出异常代码。
在我担心的情况下,在每个hashCode()/equals()
没有意义的实现中,我们总是重复同样的事情:
@Override
public int hashCode() {
throw new UnsupportedOperationException( "contract violation: calling hashCode() on such an object makes no sense" );
}
@Override
public boolean equals( Object o ) {
throw new UnsupportedOperationException( "contract violation: calling equals() on such an object makes no sense" );
}
然而,这很容易出错:我们可能会错误地忘记剪切/粘贴它,这可能会导致用户误用这些对象(比如试图将它们放入默认的 Java 集合中)。
或者如果不能通过注释来创建这种行为,AOP 会起作用吗?
有趣的是,真正的问题是 Java 层次结构的存在hashCode()
和equals()
顶部,这在某些情况下根本没有意义。但是那么我们如何干净地处理这个问题呢?