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

pst*_*ton 38 java inheritance classcastexception

我很困惑......

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

public class Device implements AutocompleteResult
{...}
Run Code Online (Sandbox Code Playgroud)

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

Object match = ...;
log.debug(match.getClass()); // Outputs 'Device'
log.debug(match.getClass().getInterfaces()[0]); // Outputs 'AutocompleteResult'
Run Code Online (Sandbox Code Playgroud)

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

AutocompleteResult result = (AutocompleteResult) match;
Run Code Online (Sandbox Code Playgroud)

我得到了ClassCastException!

ClassCastException: Device cannot be cast to AutocompleteResult
Run Code Online (Sandbox Code Playgroud)

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

log.debug(AutocompleteResult.class.isAssignableFrom(Device.class));
Run Code Online (Sandbox Code Playgroud)

来自文档:

确定是否类或由这类对象表示接口是任一相同,或是一个超类或的超接口,由指定的Class参数所表示的类或接口.

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

谢谢.

Joa*_*uer 64

如果两个不同的类加载器加载一个名为类可能出现这种情况AutocompleteResult.

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

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

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

  • +1:尝试`log.debug(match.getClass().getInterfaces()[0] .getClassLoader()); log.debug(AutocompleteResult.class.getClassLoader())` (3认同)