我已经编写了这个测试类,我想知道为什么代理对象确实具有与原始对象相同的hashCode。有谁知道为什么?
public class Main {
public static void main(String[] args) {
final Service realSubject = new Subject_A();
final Service proxySubject = ProxyGenerator.makeProxy(Service.class, realSubject);
final String hello = proxySubject.work("Hello");
System.out.println("hello = " + hello);
System.out.println("\n");
System.out.println("realSubject: " + realSubject);
System.out.println("proxySubject: " + proxySubject);
}
}
这是一个示例输出:
in Subject_A#work: str = Hello
hello = Hello_DONE
realSubject: at.me.proxy.Subject_A@4f4a7090
proxySubject: at.me.proxy.Subject_A@4f4a7090
答案 0 :(得分:3)
代理用于间接访问底层对象,就客户端代码而言,应隐藏代理的存在。
通常,此模式用于诸如spring和hibernate之类的框架中,以使用事务或安全功能来装饰对象。
鉴于上述情况,代理对象与hashcode()
,equals()
和toString()
具有相同的输出作为基础对象是很自然的。
修改强>
根据@Holger
的更正进行更新首先,您观察到的是toString()
调用的相同输出,而不是hashcode()
。
通过代理实现equals()
比初看起来更微妙一些。在equals()
的典型实现中,根据等于契约将违反对称属性:
对于任何非空引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才应返回true。
你有
// works since you delegate same instance of wrapped class to underyling object
proxy.equals(wrapped); // true
但
wrapped.equals(proxy); // false
由于:
// proxy class != wrapped class
if (this.getClass() != obj.getClass()) {
return false;
}
正如@Holger建议的那样,包含相同底层实例的两个代理可以相等而不会违反对称性。
使代理等于包装实例的选项(反之亦然)可以是通过接口成员( getters )为包含对象相等性的状态实现equals,并将类与此接口进行比较。由于代理和底层对象都符合这个接口,因此它们是相同的。