equals(Object)
method to compare two Proxy
objects always evaluates to false
, even when the receiver and the parameter are the same instance. Today's topic is how to implement the InvocationHandler
interface such that the equals(Object)
method is handled correctly.The solution is to intercept the invocation of the
equals(Object)
method and invoke it with an unwrapped receiver and parameter. Here's how...
public class MyInvocationHandler extends Object implements InvocationHandler {
private Object object;
public MyInvocationHandler(Object object) {
super();
this.object = object;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
String name = method.getName();
if (name.equals("equals") && args.length == 1) {
MyInvocationHandler handler = toMyInvocationHandler(args [ 0 ]);
if (handler != null) {
Object[] parameters= new Object[] {
handler.object
};
result = method.invoke(object, parameters);
}
}
if (result == null) {
result = method.invoke(object, args);
}
return result;
}
private MyInvocationHandler toMyInvocationHandler(Object parameter) {
InvocationHandler handler = Proxy.getInvocationHandler(parameter);
boolean valid = handler instanceof MyInvocationHandler;
if (valid == false) return null;
MyInvocationHandler myHandler = (MyInvocationHandler) handler;
return myHandler;
}
}
Rather than anonymously implementing the
InvocationHandler
interface, we have the class MyInvocationHandler
. The object
field is used to store the object that is being proxied.We must intercept the invocation of the
equals(Object)
method, and where the parameter is an instance of MyInvocationHandler
, we must invoke the Method
, passing as a parameter the MyInvocationHandler
instance's object
field.This technique of unwrapping the parameter
Proxy
only works when the proxy is one that has an invocation handler that is an instance of MyInvocationHandler
. In cases where the parameter is not an appropriate proxy, execute continues as normal in the invocation handler.
1 comment:
Hum - doesn't work well no? Doing this, you bypass the proxy in equals, so if equals() calls other methods of the object, it's not through the proxy anymore.
Looks to me it's only safe if your object class does not overwrite equals().
Post a Comment