我有许多类都覆盖它们的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());
// ...
}
}
答案 0 :(得分:0)
您的类可以扩展一个实现equals和hashCode的公共基类。在这种情况下,您必须将MyClass
的引用替换为this.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();
}
在一个不相关的注释中:当对象没有内部状态时,为什么不使用Singleton pattern?