我有;

List<String> stringList = new ArrayList<String>();
List<Integer> integerList = new ArrayList<Integer>();

是否有(简单)方法检索列表的泛型类型?


当前回答

在运行时,不可以。

但是,通过反射可以访问类型参数。试一试

for(Field field : this.getDeclaredFields()) {
    System.out.println(field.getGenericType())
}

方法getGenericType()返回一个Type对象。在这种情况下,它将是一个paramtrizedtype的实例,它又有方法getRawType()(在这种情况下,它将包含List.class)和getActualTypeArguments(),它将返回一个数组(在这种情况下,长度为1,包含String.class或Integer.class)。

其他回答

正如其他人所说,唯一正确的答案是否定的,该类型已被删除。

如果列表的元素数目非零,则可以研究第一个元素的类型(例如,使用它的getClass方法)。这不会告诉您列表的泛型类型,但可以合理地假设泛型类型是列表中类型的某个超类。

我不提倡这种方法,但在遇到困难时,它可能会有用。

如果这些实际上是某个类的字段,那么你可以通过反射来获得它们:

package test;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;

public class Test {

    List<String> stringList = new ArrayList<String>();
    List<Integer> integerList = new ArrayList<Integer>();

    public static void main(String... args) throws Exception {
        Field stringListField = Test.class.getDeclaredField("stringList");
        ParameterizedType stringListType = (ParameterizedType) stringListField.getGenericType();
        Class<?> stringListClass = (Class<?>) stringListType.getActualTypeArguments()[0];
        System.out.println(stringListClass); // class java.lang.String.

        Field integerListField = Test.class.getDeclaredField("integerList");
        ParameterizedType integerListType = (ParameterizedType) integerListField.getGenericType();
        Class<?> integerListClass = (Class<?>) integerListType.getActualTypeArguments()[0];
        System.out.println(integerListClass); // class java.lang.Integer.
    }
}

对于参数类型和方法的返回类型也可以这样做。

但是如果它们在类/方法的相同范围内,而您需要知道它们,那么就没有必要知道它们,因为您已经自己声明了它们。

查找一个字段的泛型类型:

((Class)((ParameterizedType)field.getGenericType()).getActualTypeArguments()[0]).getSimpleName()
import org.junit.Assert;
import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class GenericTypeOfCollectionTest {
    public class FormBean {
    }

    public class MyClazz {
        private List<FormBean> list = new ArrayList<FormBean>();
    }

    @Test
    public void testName() throws Exception {
        Field[] fields = MyClazz.class.getFields();
        for (Field field : fields) {
            //1. Check if field is of Collection Type
            if (Collection.class.isAssignableFrom(field.getType())) {
                //2. Get Generic type of your field
                Class fieldGenericType = getFieldGenericType(field);
                //3. Compare with <FromBean>
                Assert.assertTrue("List<FormBean>",
                  FormBean.class.isAssignableFrom(fieldGenericType));
            }
        }
    }

    //Returns generic type of any field
    public Class getFieldGenericType(Field field) {
        if (ParameterizedType.class.isAssignableFrom(field.getGenericType().getClass())) {
            ParameterizedType genericType =
             (ParameterizedType) field.getGenericType();
            return ((Class)
              (genericType.getActualTypeArguments()[0])).getSuperclass();
        }
        //Returns dummy Boolean Class to compare with ValueObject & FormBean
        return new Boolean(false).getClass();
    }
}

在运行时,不可以。

但是,通过反射可以访问类型参数。试一试

for(Field field : this.getDeclaredFields()) {
    System.out.println(field.getGenericType())
}

方法getGenericType()返回一个Type对象。在这种情况下,它将是一个paramtrizedtype的实例,它又有方法getRawType()(在这种情况下,它将包含List.class)和getActualTypeArguments(),它将返回一个数组(在这种情况下,长度为1,包含String.class或Integer.class)。