如何确定其中一个已实现接口的泛型参数?

时间:2015-01-09 07:01:04

标签: java generics reflection

我想要通用标记接口,以便标记包含一些类信息。

现在,如何知道给定标签与哪个类进行参数化?

在下面的代码中,我正在获取一个对象,然后查找标记MyClass2,然后希望提取标记的参数(MyClass3

package tests.java;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class Try_GenericRuntime {

    public static class MyClass1 implements MyClass2<MyClass3>, MyClass4<MyClass5 >{
    }

    interface MyClass2<T> {
    }

    interface MyClass4<T> {
    }

    interface MyClass3 {
    }

    interface MyClass5 {
    }

    @SuppressWarnings("unchecked")
    public static void main(String[] args) {


        MyClass1 a = new MyClass1();

        // how to derive/reach MyClass3?

        Type[] ifaces = a.getClass().getGenericInterfaces();

        Type iface;

        Type[] params;

        for(int i=0; i<ifaces.length; ++i) {
            iface = ifaces[i];
            if( ((Class)iface).isAssignableFrom(MyClass2.class) ) {
                params = ((ParameterizedType)iface).getActualTypeArguments();
                System.out.println(params[0].toString());
            }
        }

    }
}

此代码提供sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class异常消息。

由于ParameterizedTypeClass之间不兼容,其他变体也存在问题。

2 个答案:

答案 0 :(得分:3)

您可以在此处使用getRawType()

for(int i=0; i<ifaces.length; ++i) {
    iface = ifaces[i];
    final ParameterizedType parameterizedType = (ParameterizedType) iface;
    if(((Class<?>) parameterizedType.getRawType()).isAssignableFrom(MyClass2.class) ) {
        params = parameterizedType.getActualTypeArguments();
        System.out.println(params[0].toString());
    }
}

输出interface tests.java.Try_GenericRuntime$MyClass3

答案 1 :(得分:1)

使用TypeTools

Class<?> typeArg = TypeResolver.resolveRawArgument(MyClass2.class, MyClass1.class);
assert typeArg == MyClass3.class;