I'm writing an application where I need to implement functional interfaces on runtime. I don't know in advance which interfaces to implement, but can resolve the Method
object using reflection from the interface's Class
object.
For the purpose of simplifying the question, let's say that I'm passing a Function
object containing the implementation of the method.
Straight-forward stuff:
@SuppressWarnings("unchecked")
private <T> T implement(Class<T> interfaceType, Method m, Function<Object[], ?> f) {
return (T) Proxy.newProxyInstance(
getClass().getClassLoader(),
new Class<?>[]{interfaceType},
(proxy, method, args) -> {
if (method.equals(m)) {
return f.apply(args);
}
// Calls to toString, hashCode, and equals go here.
throw new UnsupportedOperationException(method.getName());
}
);
}
So calls to toString
, hashCode
, and equals
currently fail. I clearly don't want that.
From the docs of java.lang.reflect.Proxy
:
An invocation of the
hashCode
,equals
, ortoString
methods declared injava.lang.Object
on a proxy instance will be encoded and dispatched to the invocation handler's invoke method in the same manner as interface method invocations are encoded and dispatched, as described above. The declaring class of theMethod
object passed to invoke will bejava.lang.Object
. Other public methods of a proxy instance inherited fromjava.lang.Object
are not overridden by a proxy class, so invocations of those methods behave like they do for instances ofjava.lang.Object
.
So I can override these methods however I want. That's cool, but I would prefer not to.
Sure, I could make dummy implementations that do more or less the same thing (except for hashCode
which is native
) or capture some other dummy object (maybe the invocation handler itself) and invoke the method on that one. But I feel like I should be able to just "fall through" to the methods inherited from java.lang.Object
the usual way. Or in other words, call the equivalent of super.hashCode()
etc. directly on proxy
.
Is there a good/standard way of doing that?
Aucun commentaire:
Enregistrer un commentaire