我正在写一个应用程序,需要在运行时实现函数接口,我事先不知道要实现哪些接口,但是可以使用接口的Class
对象的反射来解析Method
对象。
为了简化问题,假设我正在传递一个包含方法实现的Function
对象。
直截了当的东西:
@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());
}
);
}
因此,对toString
、hashCode
和equals
的调用当前失败,我显然不希望出现这种情况。
从java.lang.reflect.Proxy
的docs开始:
对java.lang.Object
中声明的hashCode
、equals
或toString
方法在代理示例上的调用将被编码并分派到调用处理程序的invoke方法,其方式与接口方法调用被编码和分派的方式相同。被传递来调用的Method
对象的声明类将是java.lang.Object
.从java.lang.Object
继承的代理示例的其他公共方法不被代理类覆盖,因此这些方法的调用的行为与它们对java.lang.Object
的示例所做的一样。
所以我可以随意重写这些方法。这很酷,但我不希望这样。
当然,我可以创建一些虚拟实现来完成或多或少相同的任务(hashCode
除外,它是native
)或捕获一些其他虚拟对象(可能是调用处理程序本身)并调用那个处理程序上的方法。但是我觉得我应该能够像通常的方式一样“通过”从java.lang.Object
继承的方法。或者换句话说,直接在proxy
上调用super.hashCode()
等的等效项。
有什么好的/标准的方法吗?
1条答案
按热度按时间nkkqxpd91#
根据评论中的建议,我最终定义了以下基本调用处理程序:
然后使用以下命令创建代理