3

这篇文章中,我提出了一个使用接口和匿名类的解决方案。但是,要实现一件事:hashCodeandequals方法。

但是我发现实现接口的匿名类很难实现equals。在该示例中,接口是Pair<L,R>,并且工厂方法Pairs.makePair将为它返回一个匿名实现。假设我添加了一个equals实现。用户可以使用不同的代码实现他们自己的Pair<L,R>equals,因此调用userobj.equals(makepairobj)将输入他们的代码,makepairobj.equals(userobj)并将输入我的代码。因为我无法控制他们的代码,所以很难确保equals对称,这是良好实现所必需的。

我相信这个问题在其他情况下很常见,所以我想知道这个问题一般是如何解决的?

编辑:在典型的类中,实现equals将检查参数类型以确保它与自己的相同。这保证只调用实现代码来比较对象。但是,匿名类没有名称,无法使用instanceof. 我能做的是确保它是实现接口/类的实例。这不足以防止上述情况。

4

3 回答 3

1

您可以使用this.getClass()(使用==isAssignableFrom())来比较类型。

编辑

如:

public boolean equals(Object obj) {
    if (getClass() == obj.getClass()) {
        // do whatever
    }
    return false;
}
于 2012-11-09T03:55:21.037 回答
1

通常,当您制作这样的接口时,它需要实现类来实现equalshashCode遵循一些约定。例如,如果您查看java.util.List界面,它要求列表相等,只要它们具有相同的长度和相同顺序的相同元素,并且它指定了hashCode基于元素的哈希码计算的公式。

因此,“很难确保等于对称”不应该成为问题。

于 2012-11-09T04:08:54.563 回答
1

您遇到的问题表明匿名类是错误的实现方式。

匿名类是实现接口或扩展类的简单方法。它是纯粹的语法糖,没有额外的功能或其他优势。它们(可能是错误的)旨在使您的代码更简单、更易读。如果匿名类反而使您的代码复杂化,请不要使用它。

许多过去非常适合匿名类的情况现在由 lambdas 更好地服务。如果一个类有两个或三个方法,试图把它放在一个匿名类中会使你的代码难以阅读;无论如何,它应该是一个内部类。

于 2016-08-10T15:26:06.077 回答