无法强制转换为已实现的界面

时间:2023-02-07 02:57:14

i'm very confused...

我很困惑......

I have a class which directly implements an interface:

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

public class Device implements AutocompleteResult
{...}

Here is proof that I'm looking at the right variables:

这证明我正在寻找正确的变量:

Object match = ...;
log.debug(match.getClass()); // Outputs 'Device'
log.debug(match.getClass().getInterfaces()[0]); // Outputs 'AutocompleteResult'

Yet when I try to cast an instance of the class to the interface:

然而,当我尝试将类的实例强制转换为接口时:

AutocompleteResult result = (AutocompleteResult) match;

I get a ClassCastException!

我得到一个ClassCastException!

ClassCastException: Device cannot be cast to AutocompleteResult

Also, isAssignableFrom returns false and i'm not sure why:

此外,isAssignableFrom返回false,我不知道为什么:

log.debug(AutocompleteResult.class.isAssignableFrom(Device.class));

from the doc:

来自文档:

Determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter.

确定此Class对象表示的类或接口是否与指定的Class参数表示的类或接口相同,或者是它们的超类或超接口。

Shouldn't I always be able to cast a object to an interface its class implements?

我不应该总是能够将对象强制转换为其类实现的接口吗?

Thanks.

2 个解决方案

#1


59  

This can happen if two different classloaders load a class named AutocompleteResult.

如果两个不同的类加载器加载名为AutocompleteResult的类,则会发生这种情况。

These two classes are then treated as entirely different classes, even if they have the same package and name (and even implementation/fields/methods).

然后将这两个类视为完全不同的类,即使它们具有相同的包和名称(甚至是实现/字段/方法)。

A common cause for this is if you use some kind of plugin system and both your base classes and the plugin classes provide the same class.

一个常见的原因是如果你使用某种插件系统,你的基类和插件类都提供相同的类。

To check for this issue print the value returned by Class.getClassLoader() on both offending classes (i.e. the class of the interface implemented by Device and the result of AutocompleteResult.class).

要检查此问题,请在两个有问题的类(即Device实现的接口类和AutocompleteResult.class的结果)上打印Class.getClassLoader()返回的值。

#2


0  

AKA when Java apparently doesn't Java.

当Java显然不是Java时,AKA。

I hit this problem recently with Play Framework 2.6.3, what helped me was this: https://www.playframework.com/documentation/2.6.x/ThreadPools#Application-class-loader

我最近使用Play Framework 2.6.3解决了这个问题,帮助我的是:https://www.playframework.com/documentation/2.6.x/ThreadPools#Application-class-loader

I leave this info here for the people that might have the same problem.

我在这里留下这些信息给那些可能有同样问题的人。

To make it clearer, what helps is:

为了更清楚,有用的是:

Injecting Application on an Eager Singleton and then using its classloader to load the classes I was having issues with.

在Eager Singleton上注入应用程序,然后使用其类加载器加载我遇到问题的类。

To make it clearer

使它更清楚

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);

The example here https://playframework.com/documentation/2.6.x/JavaDependencyInjection#Configurable-bindings

这里的例子https://playframework.com/documentation/2.6.x/JavaDependencyInjection#Configurable-bindings

That uses Environment often throws a frustrating ClassNotFoundException

使用Environment通常会引发令人沮丧的ClassNotFoundException

Cheers

#1


59  

This can happen if two different classloaders load a class named AutocompleteResult.

如果两个不同的类加载器加载名为AutocompleteResult的类,则会发生这种情况。

These two classes are then treated as entirely different classes, even if they have the same package and name (and even implementation/fields/methods).

然后将这两个类视为完全不同的类,即使它们具有相同的包和名称(甚至是实现/字段/方法)。

A common cause for this is if you use some kind of plugin system and both your base classes and the plugin classes provide the same class.

一个常见的原因是如果你使用某种插件系统,你的基类和插件类都提供相同的类。

To check for this issue print the value returned by Class.getClassLoader() on both offending classes (i.e. the class of the interface implemented by Device and the result of AutocompleteResult.class).

要检查此问题,请在两个有问题的类(即Device实现的接口类和AutocompleteResult.class的结果)上打印Class.getClassLoader()返回的值。

#2


0  

AKA when Java apparently doesn't Java.

当Java显然不是Java时,AKA。

I hit this problem recently with Play Framework 2.6.3, what helped me was this: https://www.playframework.com/documentation/2.6.x/ThreadPools#Application-class-loader

我最近使用Play Framework 2.6.3解决了这个问题,帮助我的是:https://www.playframework.com/documentation/2.6.x/ThreadPools#Application-class-loader

I leave this info here for the people that might have the same problem.

我在这里留下这些信息给那些可能有同样问题的人。

To make it clearer, what helps is:

为了更清楚,有用的是:

Injecting Application on an Eager Singleton and then using its classloader to load the classes I was having issues with.

在Eager Singleton上注入应用程序,然后使用其类加载器加载我遇到问题的类。

To make it clearer

使它更清楚

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);

The example here https://playframework.com/documentation/2.6.x/JavaDependencyInjection#Configurable-bindings

这里的例子https://playframework.com/documentation/2.6.x/JavaDependencyInjection#Configurable-bindings

That uses Environment often throws a frustrating ClassNotFoundException

使用Environment通常会引发令人沮丧的ClassNotFoundException

Cheers