2011-11-07 92 views
29

我很困惑...無法投射到實現的接口

我有直接實現接口的類:

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,我不知道爲什麼:

​​

doc

判定此類類或接口代表對象是或者是相同的,或者是超類或者是superinterf ace,由指定的Class參數表示的類或接口。

我不應該總是能夠投出對象的接口的類實現的?

謝謝。

+0

是的,你應該! (你甚至不需要明確的轉換。)請張貼一些自包含的示例代碼來演示問題。 –

回答

54

如果兩個不同的類加載器加載一個名爲AutocompleteResult類可能發生這種情況。

這兩個類然後被視爲完全不同的類,即使它們具有相同的包和名稱(甚至實現/字段/方法)。

這是一個常見的原因是,如果您使用某種插件系統,並且您的基類和插件類提供相同的類。

要檢查這個問題,打印由Class.getClassLoader()兩個違規類返回的值(即類的DeviceAutocompleteResult.class結果實現的接口)。

+1

哇,謝謝!我真的在這一張上撕下了頭髮。我會嘗試解決類加載問題,現在... – pstanton

+3

+1:嘗試'log.debug(match.getClass()。getInterfaces()[0] .getClassLoader()); log.debug(AutocompleteResult.class.getClassLoader())' –

+0

我的問題是我有錯誤的導入類,這有助於我確定:'Class [] interfaces = match.getClass()。getInterfaces(); for(int i = 0; i toobsco42

0

AKA時的Java顯然不會的Java。

我最近襲擊了這個問題,播放框架2.6.3,是什麼幫助我是這樣的: https://www.playframework.com/documentation/2.6.x/ThreadPools#Application-class-loader

我離開這裏了這個信息對於可能有同樣的問題的人。

使其更清晰,有什麼可以幫助是:

注入上的渴望辛格爾頓應用程序,然後使用它的類加載器加載我是有問題的類。

使其更清晰

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

乾杯