强制类重写.equals方法

我有一堆实现了一个通用接口的类:Command。

而这一堆class去了一个地图。

为了使地图工作正常,我需要实现Command的每个类来覆盖Object.equals(Object other)方法。

没关系。

但是我想强迫平等的压倒一切。 =>执行命令的人不会覆盖等于编译错误。

这可能吗?

编辑:顺便说一句,我还需要强制重写hashcode …

不,你不能。 但是,你可以做的是使用抽象基类而不是接口,并使equals()抽象:

 abstract class Command { // put other methods from Command interface here public abstract boolean equals(Object other); public abstract int hashCode(); } 

Command子类必须提供自己的equals和hashCode方法。

强制API用户扩展基类通常是不好的做法,但在这种情况下可能是合理的。 另外,如果你使Command成为一个抽象的基类而不是一个接口,而不是引入一个人为的基类以及命令接口,那么你的API用户就没有错误的风险。

你能扩展你的对象从一个抽象的XObject而不是java.lang.Object?

 public abstract class XObject extends Object { @Override public abstract boolean equals(Object o); } 

抽象类不会工作,如果你有一个孙子,因为它的父亲已经覆盖了equals和hashCode方法,然后你再次从头开始。

尝试使用annotatins和APT( http://docs.oracle.com/javase/1.5.0/docs/guide/apt/GettingStarted.html )来完成它。

这只有在Command是一个接口或一个抽象类时才可能,其中equals(..)是一个被声明为抽象的方法。

问题是Object是所有对象的超类,已经定义了这个方法。

如果你想表明这是一个问题(在运行时),你可以抛出一个exception,强制你的API的用户覆盖它。 但是在编译时是不可能的,至less据我所知。

尝试解决它,通过具有特定于API的方法,例如CommandEquals。 另一个select是(如前所述)扩展了另一个定义了一个Equals抽象方法的类。

那么如果你想要一个运行时检查,你可以做这样的事情:

  interface Foo{ } class A implements Foo { } class B implements Foo { @Override public boolean equals(Object obj) { return super.equals(obj); } } public static void main(String[] args) { Class<A> clazzA = A.class; Class<B> clazzB = B.class; Class<Object> objectClass = Object.class; try { Method methodFromObject = objectClass.getMethod("equals",Object.class); Method methodFromA = clazzA.getMethod("equals",Object.class); Method methodFromB = clazzB.getMethod("equals",Object.class); System.out.println("Object == A" + methodFromObject.equals(methodFromA)); System.out.println("Object == B" + methodFromObject.equals(methodFromB)); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } 

第一个将打印为true,第二个将打印为false。 如果你想要它编译时间看起来像唯一的select是创build一个注释,并使用注释处理工具来检查所有注释的类覆盖等于。

 interface A{ public boolean equal2(Object obj); } abstract class B implements A { @Override public boolean equals(Object obj) { return equal2(obj); } } class C extends B { public boolean equal2(Object obj) { throw new UnsupportedOperationException("Not supported yet."); } } 

由于equals()是从Objectinheritance的,所以我怀疑你不能强制这样做,因为对于每一个types都有一个自动inheritance的equals()可用实现。

我不认为有可能强制重写equals,因为它来自Object类。

在相关说明中,请注意,当您覆盖equals时,您需要覆盖Object类中的“hashCode”方法。 如果您要将类的实例用作Map的键,则这变得非常重要。 检查这篇文章: http : //www.artima.com/lejava/articles/equality.html提供了一些关于如何以正确的方式重写equals的提示

正如其他答案已经解释,不,你不能强迫你正在尝试的东西。

有一件事情可能“足够”,就是定义第二个接口,称之为MappableCommand。

 public interface MappableCommand { } 

在这个接口的文档中,如果类devise者已经考虑到你所陈述的要求,那么只应该实现这个(空的)接口。

然后,您可以将地图的值types设置为MappableCommand,并且只有MappableCommands可以添加到地图中。

这类似于为什么需要实现(空白)接口Serializable对于可以由Java的默认序列化机制序列化的类的逻辑。

如果这不起作用,那么你可能必须解决抛出运行时错误;

假编辑:

如果你想让这个要求更明显,你可以这样定义新的接口

 public interface MappableCommand { public void iOverrodeTheEqualsMethod(); public void seriouslyIPromiseThatIOverrodeIt(); } 

您可以在interface Command创buildboolean myEquals() ,并像下面这样创buildAdapter:

 class MyAdapter{ Command c; boolean equals(Object x) { return c.myEquals((Command)x); } } 

然后你只需要使用map.put(key, new MyAdapter(command))来代替map.put(key, command)

以下是其他一些build议解决scheme的变体:

 public abstract class CommandOverridingEquals implements Command { public abstract boolean equals(Object other); public abstract int hashcode(); } Map<String, CommandOverridingEquals> map = new HashMap<String, CommandOverridingEquals>(); 

或者如果你真的想确定,使用一个检查哈希映射; 例如

 Map<String, CommandOverridingEquals> map = Collections.checkedMap( new HashMap<String, Command>(), String.class, CommandOverridingEquals.class); 

但不pipe你做什么,你都不能阻止某人这样做:

 public class AntiFascistCommand extends CommandOverridingEquals { public boolean equals(Object other) { return super.equals(other); } public int hashcode() { return super.hashcode(); } ... } 

我倾向于认为这样的事情会引起麻烦。 例如,假设我有一堆现有的命令类来扩展一些其他的基类,并且(顺便说一下)以规定的方式覆盖equalshashcode 。 问题是,我不能使用这些类。 相反,我不得不重新实现它们,或者写一堆包装器。

海事组织,这是一个坏主意,试图迫使开发人员进入一个特定的实施模式。 最好是向Javadocs发出强烈的警告,并依靠开发人员做正确的事情

你有可能提供你自己的java.util.comparator到有问题的地图吗?