Java代理 - >为什么代理对象与原始对象具有相同的hashCode

时间:2016-08-24 07:51:36

标签: java

我已经编写了这个测试类,我想知道为什么代理对象确实具有与原始对象相同的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

1 个答案:

答案 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,并将类与此接口进行比较。由于代理和底层对象都符合这个接口,因此它们是相同的。