2

我有许多类都覆盖了它们的 equals 和 hashCode 方法,如下所示:

final class MyClass {
  public void statelessMethod() {
    // ...
  }

  @Override
  public boolean equals(Object obj) {
    return obj instanceof MyClass;
  }

  @Override
  public int hashCode() {
    return MyClass.class.hashCode();
  }
}

这个想法是,虽然类没有任何状态,但new MyClass().equals(new MyClass())应该始终是正确的。

我正在寻找的是一些我可以编写(或重用)的代码模式或实用程序类,它们将尽可能多地删除样板文件。

背景

我正在使用这种模式来定义 Guice 模块,这样如果多个模块依赖于 UtilModule(例如),我最终不会遇到由相同类型的多个绑定引起的错误。

额外背景

这种模式是从 Guice Servlets InternalServletModule 复制而来的,它使用它来允许您在注入器配置中指定多个 ServletModule 模块,而无需复制作为该类的一部分提供的绑定。

实际使用示例回答部分评论

final class UtilModule extends AbstractModule {
  public void configure() {
    // bindings and things
  }

  @Override
  public boolean equals(Object obj) {
    return obj instanceof UtilModule;
  }

  @Override
  public int hashCode() {
    return UtilModule.class.hashCode();
  }
}

取决于 UtilModule 的多个模块的示例(来自评论)

class Module1 extends AbstractModule {
  @Override
  protected void configure() {
    bind(SomeClass.class).to(SomeClassImpl.class);
    install(new UtilModule()); // needed by SomeClassImpl
  }
}

class Module2 extends AbstractModule {
  @Override
  protected void configure() {
    bind(MyService.class).in(Singleton.class);
    install(new UtilModule()); // needed by MyService
  }
}

class Main {
  public static void main(String[] args) {
    Injector injector = Guice.createInjector(
        new Module1(),
        new Module2());
    // ...
  }
}
4

1 回答 1

0

你的类都可以扩展一个实现equals和hashCode的通用基类。在这种情况下,您必须将引用替换MyClassthis.getClass()

此外,instanceof这不是您想要的,因为当 obj 属于扩展当前类的类时,它也会返回 true。这不仅不太可能是您想要的,而且还会违反 equals 的约定,因为当您将基类的实例与扩展类的实例进行比较时,调用 equals 方法会很重要(派生的是 instanceof base,但 base 不是 instanceof 派生的)。

您的基类中的实现如下所示:

@Override
public boolean equals(Object obj) {
   this.getClass().equals(obj.getClass())
}

@Override
public int hashCode() {
  return this.getClass().hashCode();
}

在不相关的说明中:当对象没有内部状态时,为什么不使用单例模式

于 2012-12-18T14:27:04.577 回答