在处理类中的特定方法时,我制作了一个动态代理作为中间人。我这样做是为了避免必须覆盖我需要控制的每个接口中的每个方法。
没有人会理解或关心的华夫饼(但可能会为问题添加更多上下文):
在我要给出的示例中,我尝试使其具有通用性,以便您可以编译它以测试和运行自己,但在实际情况下,我有这样的东西:
interface CommandSender
interface ConsoleCommandSender extends CommandSender
interface Player extends CommandSender
如果我要创建一个ConsoleCommandSender
实例的代理,则生成的代理应该可以转换为CommandSender
. 实际上,ConsoleCommandSender
并没有列出它的所有接口,getInterfaces()
并且会发生这种情况:
java.lang.ClassCastException: $Proxy18 cannot be cast to org.bukkit.command.CommandSender
Player 类没有这个问题,并且总是可以转换为CommandSender
.
真正的问题:
那么,使用以下代码作为起点,如何成功地将 表示的代理转换为myProxy
所需的格式,而不必担心ClassCastException
?
以下代码将成功编译和运行,但希望您通过转换为 aList
而不是ArrayList
.
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
public class ProxyClass implements InvocationHandler {
private Object classProxy;
public static void main(String[] args) {
// Example declaration
// (I know the proxy should really be cast as an ArrayList
// but this is my point, it SHOULD work anyway)
ArrayList methodObject = new ArrayList<String>();
List<String> myProxy = (List<String>)ProxyClass.newInstance(methodObject, false);
// Example usage
myProxy.add("Hello World!");
System.out.println(myProxy.get(0));
}
public static Object newInstance(Object proxy, boolean silent) {
return Proxy.newProxyInstance(
proxy.getClass().getClassLoader(),
proxy.getClass().getInterfaces(),
new ProxyClass(proxy));
}
private ProxyClass(Object proxy) {
this.classProxy = proxy;
}
// Is called whenever a method is invoked
public Object invoke(Object p, Method m, Object[] args) throws Throwable {
return m.invoke(classProxy, args);
}
}
在我就这个问题的初步部分所做的另一个线程上,一个人评论说我可以使用该<T>
变量将另一个有效接口添加到列表中。虽然我并不真正了解如何实现这一点,但这似乎是一个好的开始。