我有一堆类的谁实现共同的接口:命令。
而这一群类的都到了地图。
要获得地图正常工作,我需要每一个谁执行命令覆盖类Object.equals(Object other)
的方法。
没关系。
但我喜欢对子级向力等于压倒一切的。 =>有一个编译错误时,谁执行命令的东西不重写equals。
这可能吗?
编辑:BTW,我还需要迫使哈希码的覆盖...
我有一堆类的谁实现共同的接口:命令。
而这一群类的都到了地图。
要获得地图正常工作,我需要每一个谁执行命令覆盖类Object.equals(Object other)
的方法。
没关系。
但我喜欢对子级向力等于压倒一切的。 =>有一个编译错误时,谁执行命令的东西不重写equals。
这可能吗?
编辑:BTW,我还需要迫使哈希码的覆盖...
不,你不能。 你能做什么,但是,使用一个抽象基类,而不是一个接口,使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的用户的风险。
你可以从一个抽象的X对象,而不是延长java.lang.Object继承你的对象?
public abstract class XObject
extends Object
{
@Override
public abstract boolean equals(Object o);
}
如果你有一个孙子,因为其父亲已经overrided既equals和hashCode方法,然后你一遍有你的问题抽象类将无法正常工作。
尝试使用annotatins和APT( http://docs.oracle.com/javase/1.5.0/docs/guide/apt/GettingStarted.html )来完成它。
这只会是可能的,如果命令是接口或抽象类,其中的equals(..)被声明为抽象的方法。
的问题是,对象,这是所有对象的超,已经定义了此方法。
如果你想表明这是一个问题(在运行时),你可以抛出一个异常,强迫你的API的用户覆盖它。 但是,这是不可能在编译时,至少据我所知。
尝试解决它,由具有特定API的方法,如CommandEquals。 另一种选择是(如所提到的)延伸另一类其限定的Equals抽象方法。
您可以创建boolean myEquals()
在interface Command
,并创建适配器是这样的:
class MyAdapter{
Command c;
boolean equals(Object x) {
return c.myEquals((Command)x);
}
}
然后你只需要使用map.put(key, new MyAdapter(command))
而不是map.put(key, command)
那么,如果你想有一个运行时检查,你可以这样做:
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();
}
}
将第一个和虚假第二打印真实。 如果你想让它编译时看起来像唯一的选择是创建一个注释,并使用注释处理工具来检查所有注释类重写等于。
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()
是继承自Object
,我怀疑你真的不能强迫,由于每种类型有一个自动继承实现equals()
可用。
我不认为这是可能的力等于压倒一切的,因为它来自于Object类。
在一个相关的说明,请注意,你需要重写从当过改变了equals Object类“的hashCode”方法。 如果你要使用你的类的实例作为地图的钥匙,这变得espeically重要。 检查这篇文章: http://www.artima.com/lejava/articles/equality.html它提供了有关如何覆盖一些提示等于以正确的方式
至于其他的答案已经解释,不,你不能强迫你尝试之类的话。
可能的工作“足够”有一两件事是确定的第二接口,称之为一个MappableCommand。
public interface MappableCommand
{
}
在你的文档,该接口指示类应该只实现这个(空)接口,如果类的设计者已经考虑你所说的要求。
然后你可以设置你的地图MappableCommand的值类型,只有MappableCommands将能够被添加到地图中。
这类似于后面为什么一个需要实现的(空白)接口,可序列化的,可以通过Java的默认序列化机制进行序列化类的逻辑。
如果这也不行,那你可能不得不接受抛出运行时错误;
假编辑:
如果你想使这个需求更加明显,你可以定义新的接口这样
public interface MappableCommand
{
public void iOverrodeTheEqualsMethod();
public void seriouslyIPromiseThatIOverrodeIt();
}
下面是一些其他提出的解决方案的变化:
public abstract class CommandOverridingEquals implements Command {
public abstract boolean equals(Object other);
public abstract int hashcode();
}
Map<String, CommandOverridingEquals> map =
new HashMap<String, CommandOverridingEquals>();
或者,如果你真的想可以肯定,使用HashMap的检查; 例如
Map<String, CommandOverridingEquals> map = Collections.checkedMap(
new HashMap<String, Command>(),
String.class, CommandOverridingEquals.class);
但是,不管你做什么,你不能阻止别人这样做:
public class AntiFascistCommand extends CommandOverridingEquals {
public boolean equals(Object other) { return super.equals(other); }
public int hashcode() { return super.hashcode(); }
...
}
我倾向于认为这种事情会引起麻烦走下赛场。 例如,假设我有一堆延伸一些其他基类,和(捎带)重写现有的命令类的equals
和hashcode
在规定的方式。 问题是,我不能使用这些类。 相反,我不得不重新实现他们或写一堆包装的。
国际海事组织,这是一个坏主意,试图给开发者强行进入一个特定的实现模式。 这将是更好地把一些强有力的警告到的javadoc,依靠开发者做正确的事 。
是否有可能为你提供自己java.util.comparator
有问题的地图吗?