Ala*_*n47 5 java proxy equals dynamic-proxy
我有史以来第一次使用标准JDK动态代理实现自己的代理类.它的工作原理相当不错,除了一个细节:equals(...)方法.
我们假设我们有一个像这样的简单接口,我们要代理它:
public interface MyInterface {
public String getID();
public void setID(String id);
}
Run Code Online (Sandbox Code Playgroud)
......我们的实现看起来是这样的(标准的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;
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,当我创建代理时,该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
Run Code Online (Sandbox Code Playgroud)
本文还讨论了这一点.
我的问题是:如果我想要提供所有四个"平等"案例true,那么最好的(即最安全和最少侵入性)方式是什么?
小智 2
这是 equals() 的可能替代方案;
public final boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (! (obj instanceof MyInterface)) // neither a Proxy nor a MyImplementation
return false;
MyInterface other = (MyInterface) obj;
if (this.getID() == null) {
if (other.getID() != null) {
return false;
}
} else if (!this.getID().equals(other.getID())) {
return false;
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
此代码使用 getID() 而不是直接访问该字段。到目前为止,效果很好。