【发布时间】:2012-09-29 22:50:55
【问题描述】:
我正在为这些接口实现一个值对象:
interface FooConsumer
{
public void setFoo(FooKey key, Foo foo);
public Foo getFoo(FooKey key);
}
// intent is for this to be a value object with equivalence based on
// name and serial number
interface FooKey
{
public String getName();
public int getSerialNumber();
}
从我读到的内容(例如在Enforce "equals" in an interface 和toString(), equals(), and hashCode() in an interface)看来,建议是提供一个抽象基类,例如
abstract class AbstractFooKey
{
final private String name;
final private int serialNumber
public AbstractFooKey(String name, int serialNumber)
{
if (name == null)
throw new NullPointerException("name must not be null");
this.name = name;
this.serialNumber = serialNumber;
}
@Override public boolean equals(Object other)
{
if (other == this)
return true;
if (!(other instanceof FooKey))
return false;
return getName().equals(other.getName()
&& getSerialNumber() == other.getSerialNumber()
&& hashCode() == other.hashCode(); // ***
}
@Override public int hashCode()
{
return getName().hashCode() + getSerialNumber()*37;
}
}
我的问题是关于我在此处添加的最后一点,以及如何处理使用 x 的值调用 AbstractFooKey.equals(x) 的情况,这是实现 FooKey 但没有子类的类的实例AbstractFooKey。我不知道如何处理这个;一方面,我觉得相等的语义应该只取决于 name 和 serialNumber 是否相等,但看起来 hashCodes 也必须相等才能满足 Object.equals() 的合同。
我应该是:
- 真的很松懈,忘记标记
***的行 - 放松并保留我所拥有的
- 如果
other对象不是AbstractFooKey,则从equals()返回false - 真的很严格,去掉接口 FooKey 并用一个最终的类替换它?
- 还有别的吗?
【问题讨论】:
-
行标***是不正常的。 equals() 实现通常不调用 hashCode()。