13

我的项目包括反射,我目前正在处理泛型类型。我已经设法从 List(java.util.List) 中获取泛型类型:

if(originalField.getGenericType() instanceof ParameterizedType){
    ParameterizedType pt = (ParameterizedType) originalField.getGenericType();
    Class<?> subClass = (Class<?>) pt.getActualTypeArguments()[0];
}

我也有一个Collection<String>,事实证明不能将 Collection强制转换为 ParameterizedType。

有人知道如何从集合中获取字符串(或任何类型)?

我一直在阅读有关 java 擦除的内容,所以我知道这一点,但是在将泛型从列表中删除后,我想也许有人知道另一个“技巧”。

谢谢。

编辑:我正在迭代类的所有字段:

for (Field originalField : someClass.getDeclaredFields())

然后当我面对一些List<String>领域时,使用上面的代码我得到了String子类变量。

4

3 回答 3

14

你的方法很好。它应该适用于List<String>Collection<String>。例如看这个示例代码:

public class Demo {

    List<String> list = new ArrayList<>();
    Collection<String> coll = new ArrayList<>();

    public static void main(String args[]){

        Class<Demo> clazz = Demo.class;
        Field[] fields = clazz.getDeclaredFields();

        for (Field field: fields) {

            Type type = field.getGenericType();

            if (type instanceof ParameterizedType) {

                ParameterizedType pType = (ParameterizedType)type;
                Type[] arr = pType.getActualTypeArguments();

                for (Type tp: arr) {
                    Class<?> clzz = (Class<?>)tp;
                    System.out.println(clzz.getName());
                }
            }
        }
    }
}

这打印出来:

java.lang.String
java.lang.String
于 2013-10-08T16:35:14.200 回答
1

据我所知,Java 完全擦除了类型,因此编译后的代码没有您分配给参数类型的值的痕迹。所有参数类型都转换为具体类型,带有类型转换和类似的东西

在我目前看到的代码中,当一个类需要知道其泛型类型的值时,它会强制将该类型(或类)的对象作为参数传递。就像是:

class A<T> {
    private final Class<T> parameterType;

    public A(Class<T> parCls) {
        parameterType = parCls;
    }

    public A(T tObj) {
        parameterType = tObj.getClass();
    }
}
于 2013-10-08T16:32:24.187 回答
0

您需要使用定义的任何类型来解析 ParameterizedType。例如,使用TypeTools

class Foo<T> {
  public T bar;
}

class StringFoo extends Foo<String> {}

Type barType = Foo.class.getDeclaredField("bar").getGenericType();
Class<?> t = TypeResolver.resolveRawClass(barType, StringFoo.class);
assert t == String.class;

这里的值T是在 StringFoo 中定义的,所以我们可以使用TypeResolver来解析我们字段类型的原始类StringFoo

于 2013-10-31T22:31:33.647 回答