无法投射到实现的界面

我很困惑...

我有一个直接实现接口的类:

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

上一篇: can't cast to implemented interface

下一篇: Using IsAssignableFrom with 'open' generic types