2

次のコードを使用して、特定の Runnable オブジェクトのプロキシを作成しようとしています。

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 を実装する別のインターフェイスを実装する場合は機能すると想定しているため、インターフェイス階層でもトラバースする必要はありません。 .

ただし、ClassCastExceptionプロキシをキャストしようとすると、次のようになりRunnableます。

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

この例外の原因を考えようとしています。指定されたオブジェクトのクラス階層は利用できません。

何か案は ?

4

2 に答える 2

2

UPDATEは役に立たないコードを削除しました。

これは問題ではありませんが、Set<Class<?>>すべてのインターフェイスを収集する場合は a を使用する必要があります。これは、階層内で同じインターフェイスの重複が発生する可能性があるためです。

于 2011-04-11T13:57:17.997 に答える
1

スーパークラスを歩くためのコードが間違っています。交換

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

superClass = superClass.getSuperclass();

それ以外の場合は、すぐに迂回してからjava.lang.Classに移動しjava.lang.Objectます。

于 2011-04-11T14:13:10.977 に答える