无法投射到实现的界面
我很困惑...
我有一个直接实现接口的类:
public class Device implements AutocompleteResult
{...}
这是证明我正在查看正确的变量:
Object match = ...;
log.debug(match.getClass()); // Outputs 'Device'
log.debug(match.getClass().getInterfaces()[0]); // Outputs 'AutocompleteResult'
然而,当我尝试将类的一个实例转换为接口时:
AutocompleteResult result = (AutocompleteResult) match;
我得到一个ClassCastException!
ClassCastException: Device cannot be cast to AutocompleteResult
此外, isAssignableFrom
返回false,我不知道为什么:
log.debug(AutocompleteResult.class.isAssignableFrom(Device.class));
来自doc:
确定 此Class对象 表示的类或接口是否与指定的Class参数表示的类或接口相同,或者是否为超类或超接口。
我不应该总是能够将对象投射到其类实现的接口上吗?
谢谢。
如果两个不同的类加载器加载名为AutocompleteResult
的类,就会发生这种情况。
这两个类然后被视为完全不同的类,即使它们具有相同的包和名称(甚至是实现/字段/方法)。
一个常见的原因是,如果你使用某种插件系统,并且你的基类和插件类都提供相同的类。
要检查此问题,在两个违规类(即由Device
实现的接口的类和AutocompleteResult.class
的结果Class.getClassLoader()
上打印由Class.getClassLoader()
返回的值。
当Java看起来不是Java时。
我最近在Play Framework 2.6.3中遇到了这个问题,这对我有什么帮助:https://www.playframework.com/documentation/2.6.x/ThreadPools#Application-class-loader
我将这些信息留给可能有同样问题的人。
为了使其更清楚,有帮助的是:
在Eager Singleton上注入应用程序,然后使用它的类加载器加载我遇到问题的类。
为了更清楚
public class Module {
@Override
public void configure {
bind(TheClassLoaderLoader.class).asEagerSingleton()
public static class TheClassLoaderLoader {
@Inject
public TheClassLoaderLoader( Application application) {
ClassLoader classloader = application.classloader();
Class<?> interfaceClass = classloader.loadClass(InterfaceClass.class.getName());
classloader.loadClass(ImplementsInterfaceClass.class.getName()).asSubclass(interfaceClass);
这里的例子https://playframework.com/documentation/2.6.x/JavaDependencyInjection#Configurable-bindings
该使用Environment
经常会抛出令人沮丧的ClassNotFoundException
干杯
链接地址: http://www.djcxy.com/p/57403.html