铸造代理 - 获取ClassCastException [英] Casting Proxies - Getting ClassCastException
问题描述
当我将一个动态代理类转换为我想要的对象时,我遇到了一些奇怪。在运行时,在某些条件下,我收到一个ClassCastException。
I'm getting some weirdness when I'm casting a Dynamic Proxy Class to the object I want it to be. At runtime, under certain conditions, I receive a ClassCastException.
为了更好地解释这一点,这里是我想使用的类/接口的定义。
In order to explain this better, here are the definitions for the classes/interfaces I want to use. Brackets have been put around any extended interfaces that (should be) irrelevant.
public interface CommandSender (extends Permissible)
public interface ConsoleCommandSender extends CommandSender, (Conversable)
public interface Player extends (HumanEntity, Conversable), CommandSender, (OfflinePlayer, PluginMessageRecipient)
完整的Javadoc可以在这里找到: http ://jd.bukkit.org/apidocs/org/bukkit/command/CommandSender.html
Full Javadocs can be found here: http://jd.bukkit.org/apidocs/org/bukkit/command/CommandSender.html
现在,这里是我的代理类的代码:
Now, here is the code for my proxy class:
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);
在运行时,此示例将生成以下内容:
At run time, this example would produce the following:
java.lang.ClassCastException: $Proxy18 cannot be cast to org.bukkit.command.CommandSender
推荐答案
创建的代理类需要传递它实现的接口,
The created proxy class need to pass the interfaces it suppose to implement,
return Proxy.newProxyInstance(
sender.getClass().getClassLoader(),
sender.getClass().getInterfaces(),
new CommandSignsMessagingProxy(sender, receiver, silent));
失败似乎发生,因为CommandSender接口可能不会从调用sender.getClass()返回getInterfaces () 方法。所以尝试看看它是否正确通过调试。如果不尝试手动发送接口的方法,看看它是否工作。
failure seems to happen because CommandSender interface may not be returned from the call sender.getClass().getInterfaces() method. So try to see if it properly passes by debugging. If not try sending the interface manually to the method and see if it works.
这篇关于铸造代理 - 获取ClassCastException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!