当我将动态代理类投射到我想要的对象时,我感到有些奇怪。在运行时,在某些情况下,我收到 ClassCastException。
为了更好地解释这一点,这里是我想要使用的类/接口的定义。任何(应该)不相关的扩展接口都被括号括起来。
public interface CommandSender (extends Permissible)
public interface ConsoleCommandSender extends CommandSender, (Conversable)
public interface Player extends (HumanEntity, Conversable), CommandSender, (OfflinePlayer, PluginMessageRecipient)
完整的 Javadocs 可以在这里找到:http: //jd.bukkit.org/apidocs/org/bukkit/command/CommandSender.html
现在,这是我的代理类的代码:
public class CommandSignsMessagingProxy implements InvocationHandler {
private Object sender;
private Object receiver;
private boolean silent;
public static Object newInstance(Object proxy) {
return newInstance(proxy, proxy, false);
}
public static Object newInstance(Object proxy, boolean silent) {
return newInstance(proxy, proxy, silent);
}
public static Object newInstance(Object sender, Object receiver) {
return newInstance(sender, receiver, false);
}
public static Object newInstance(Object sender, Object receiver, boolean silent) {
return Proxy.newProxyInstance(
sender.getClass().getClassLoader(),
sender.getClass().getInterfaces(),
new CommandSignsMessagingProxy(sender, receiver, silent));
}
private CommandSignsMessagingProxy(Object sender, Object receiver, boolean silent) {
this.sender = sender;
this.receiver = receiver;
this.silent = silent;
}
// Is called whenever a method is invoked
public Object invoke(Object p, Method m, Object[] args) throws Throwable {
Object result = null;
try {
String name = m.getName();
// If the receiver is being sent a message, only do so if the silent flag is not set
if (name == "sendMessage" || name == "sendRawMessage") {
if (!silent && receiver != null)
result = m.invoke(receiver, args);
} else {
result = m.invoke(sender, args);
}
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException("Unexpected invocation exception: " + e.getMessage());
}
return result;
}
}
这是该类的完整工作实例:
Player proxy = (Player)CommandSignsMessagingProxy.newInstance(player, false);
proxy.sendMessage("Hi! Silent is turned off, so you can see this!");
proxy.setOp(true);
proxy.other_stuff();
然而,这个不起作用:
ConsoleCommandSender ccs = plugin.getServer().getConsoleSender();
CommandSender cs = (CommandSender)CommandSignsMessagingProxy.newInstance(ccs, false);
在运行时,此示例将生成以下内容:
java.lang.ClassCastException: $Proxy18 cannot be cast to org.bukkit.command.CommandSender