这是我第一次使用标准JDK动态代理来实现自己的代理类。它运行得相当不错,但有一个细节需要注意:equals(...)方法。
假设我们有一个简单的接口,我们想要进行代理:
public interface MyInterface {
public String getID();
public void setID(String id);
}
...而我们的实现看起来像这样(标准Java Bean,具有生成的hashCode()
和equals()
):
public class MyImplementation implements MyInterface {
private String id;
public String getID() { return this.id; }
public void setID(String id) { this.id = id; }
// hash code & equals generated by eclipse
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (this.databaseId == null ? 0 :
this.id.hashCode());
return result;
}
public final boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (this.getClass() != obj.getClass()) {
return false;
}
MyImplementation other = (MyImplementation) obj;
if (this.databaseId == null) {
if (other.databaseId != null) {
return false;
}
} else if (!this.databaseId.equals(other.databaseId)) {
return false;
}
return true;
}
}
问题在于,当我创建一个代理时,
equals(...)
方法不再对称:original.equals(original); // true
proxy.equals(original); // true, as the proxy forwards the call to the wrapped object
original.equals(proxy); // false
proxy.equals(proxy); // false
这也在这篇文章中讨论过。
我的问题是:如果我希望所有四种“equals”情况都返回true
,最好(即最安全和最不具 invasive性)的方法是什么?
equals
方法。可以参考List#equals(Object)
方法的实现方式(以及在javadoc中的描述)。 - Sotirios Delimanolis