我打算使用自定义的ClassLoader导入库(jar),事实证明要求在其中一个类上设置侦听器,例如
Class<?> clazz = getInitializerClass();
Object initializer = clazz.newInstance();
// I would like the below listener to be set on this initializer reflectively
// setOnInitListener() is mathod to be called on initializer
setOnInitListener(new OnInitCompleteListener(){
@Override
public void onInit(){
}
}
问题是我没有将侦听器用作导入文件,而我只能通过动态加载类来动态获取OnInitCompleteListener.class
。
如何实现以上目标?
注意:我愿意为达到相同的目标而竭尽全力,但简单的方法将不胜感激。
答案 0 :(得分:2)
匿名类是编译时工件。它们甚至具有Java编译器可以识别它们的名称,尽管程序员无法访问。
但是,有一种解决方法:由于OnInitCompleteListener
是一个接口,因此您可以生成一个动态代理来实现您的接口:
InvocationHandler handler = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("onInit")) {
... // Listener's code goes here
}
}
};
Class<T> onInitCompleteListenerClass = ... // You get this one dynamically
Object listener = Proxy.newProxyInstance(
classLoader,
new Class[] { onInitCompleteListenerClass },
handler);
// Use listener in the reflective call to a method taking OnInitCompleteListener
MyInvocationHandler
实现InvocationHandler
接口。其invoke
方法可以检测到它是在onInit
位置被调用的,并根据需要执行工作。
答案 1 :(得分:0)
假设您的OnInitCompleteListener
类在同一类加载器中可用,而您在...中运行此代码的其余部分...
您可以对类实例进行反思来了解setOnInitListener
方法:
Method setter = clazz.getDeclaredMethod("setOnInitListener", OnInitCompleteListener.class);
setter.invoke(initializer, new OnInitCompleteListener() {
@Override
public void onInit() {
// implementation
}
});