Java:调用hashCode()和equals()时自动抛出UnsupportedOperationException的干净方法?
问题内容:
我们有一个面向对象的代码库,在很多情况下hashcode()
,它们equals()
根本不起作用,主要是由于以下原因:
除非您愿意放弃面向对象抽象的好处,否则没有办法在扩展扩展实例化类和添加值组件的同时保留平等合同。
这是来自约书亚·布洛赫(Joshua Bloch)的“有效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()
位于Java层次结构的顶部,这在很多情况下根本没有意义。但是,我们如何彻底解决这个问题呢?
问题答案:
为什么不让您的IDE(Eclipse / NetBeans /
IntelliJ)为您生成hashCode()
和equals()
方法。他们在这方面做得很好。
AOP当然可以工作,但这很复杂。这将意味着您将无法使用几乎没有集合或实用程序的这些对象。
另一个合理的解决方案是仅删除那些方法不起作用的实现,从而有效地仅将实现保留在中Object
。