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 サーブレット 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 を実装する共通の基本クラスを拡張できます。その場合、への参照を に置き換える必要がありMyClassますthis.getClass()

また、instanceofobj が現在のクラスを拡張するクラスの場合にも true を返すため、これはあなたが望むものではありません。基本クラスのインスタンスと拡張クラスのインスタンスを比較すると、どちらで equals メソッドを呼び出すかが問題になるため、これはあなたが望むものである可能性が低いだけでなく、equals の契約にも違反します。 (派生はベースのインスタンスですが、ベースは派生のインスタンスではありません)。

基本クラスの実装は次のようになります。

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

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

無関係なメモ: オブジェクトに内部状態がない場合、Singleton パターンを使用しないのはなぜですか?

于 2012-12-18T14:27:04.577 に答える