2011-04-11 38 views
2

我嘗試使用下面的代碼來創建一個給定的Runnable對象代理:ClassCastException異常當試圖建立代理對象

public class WorkInvocationHandler implements InvocationHandler { 

    public static Runnable newProxyInstance(Runnable work) 
    { 
     return (Runnable)java.lang.reflect.Proxy.newProxyInstance(
      work.getClass().getClassLoader(), 
      getInterfacesWithMarker(work), 
      new WorkInvocationHandler(work)); 
    } 

    private static Class[] getInterfacesWithMarker(Runnable work) 
    { 
     List allInterfaces = new ArrayList(); 

     // add direct interfaces 
     allInterfaces.addAll(Arrays.asList(work.getClass().getInterfaces())); 

     // add interfaces of super classes 
     Class superClass = work.getClass().getSuperclass(); 
     while (!superClass.equals(Object.class)) 
     { 
      allInterfaces.addAll(Arrays.asList(superClass.getInterfaces())); 
      superClass = superClass.getClass().getSuperclass(); 
     } 

     // add marker interface 
     allInterfaces.add(IWorkProxy.class); 

     return (Class [])allInterfaces.toArray(new Class[allInterfaces.size()]);   
    } 
} 

代理應該實現給定的對象與附加標記實現了所有接口指示代理是否已經創建的接口。 因爲我不確定給定的對象是否直接實現了Runnable,所以我也遍歷了所有的超類,但是我認爲如果它實現了另一個實現Runnable的接口,它將起作用,所以我不需要在接口上進行遍歷層次結構。

不過,我還是想投的代理Runnable時得到ClassCastException

java.lang.ClassCastException: $Proxy24 incompatible with java.lang.Runnable 

我試圖想什麼可能導致此異常。給定對象的類層次結構不可用。

任何想法?

+0

嘗試直接將所需的接口傳遞給'newProxyInstance()'(即'Array'構造的地方)的調用並查看它是否有效。 – pajton 2011-04-11 13:50:37

回答

2

UPDATE刪除無用的代碼。

這不是問題,但在收集所有接口時應使用Set<Class<?>>,因爲可以在層次結構中獲取同一接口的重複項。

+0

正確。在額外的測試中,我得到了java.lang.IllegalArgumentException:重複的接口:java.lang.Runnable。使用Set解決了這個問題 – Tamir 2011-04-11 14:35:50

1

你的代碼走超類是錯誤的。更換

superClass = superClass.getClass().getSuperclass(); 

superClass = superClass.getSuperclass(); 

否則,你會很快採取繞道java.lang.Class再到java.lang.Object

+0

有道理。所以它實際上比我想象的要簡單:)。謝謝 – Tamir 2011-04-11 14:36:52