如何获取子类的泛型类型

时间:2013-01-22 10:05:01

标签: java generics

在Java中,想象一下这些接口和类:

public interface Iface<S, T> { ... }

public class Parent<A, B> implements Iface<B, A> { ... }

public class Sub extends Parent<String, Integer> { ... }

是否有办法创建一个接受Iface的函数并获取其泛型的类型。例如,如果您输入Sub.class

public void showTypes(Class<Iface<S, T>> ifaceClass) {
    // do something...
}

//showTypes(Sub.class) --> S = Integer.class, T = String.class

编辑:关于类型擦除。如果您有ArrayList<?>,则无法知道它是哪种通用类型。但这种情况不同。如果我有一个扩展ArrayList<String>的类,我可以知道它的泛型类型(String.class)。请看这个片段:

@SuppressWarnings("serial")
public class StringList extends ArrayList<String> {
    public static void main(String... args) {
        ParameterizedType superType = 
            (ParameterizedType) StringList.class.getGenericSuperclass();
        Type[] types = superType.getActualTypeArguments();
        Class<?> clss = (Class<?>) types[0];
        System.out.println(clss);
    }
}

3 个答案:

答案 0 :(得分:2)

好吧,我找到了我想要的东西。 TypeTools是一个只有一个类的小型库,旨在实现这一目标。可惜的是,它不在Maven中央存储库中。

TypeResolver.resolveArguments(Sub.class, Iface.class) --> [java.lang.Integer, java.lang.String]

Spring在GenericTypeResolver中有类似的方法:

GenericTypeResolver.resolveTypeArguments(Sub.class, Iface.class);

答案 1 :(得分:0)

不,由于在Java中实现泛型的方式,这是不可能的。在运行期间,没有关于用于泛型参数的实际类型的信息。

您可以阅读有关type erasure here

的更多详情

答案 2 :(得分:-1)

Update 01.23:

我们和其他响应者回答了一个松散的具体问题,所以我们不应该得到-1票......不太公平......

Original answer:

不,没有办法......

在泛型主要规范中,当您使用T和S时,它将生成以下代码:

public void showTypes(Class<Iface<Object, Object>> ifaceClass) {
    // do something...
}

所以你不会知道这些信息...

您可以使用解决方案来定义泛型类的类:

public void showTypes(T type)
{
if (s instanceof Number) 
 System.out.println("Number")
if (s instanceof String) 
 System.out.println("String")
}

但是,在我看来,这不是一个选择......

它只会在运行时确定,而不是编译时间......