当前位置:  开发笔记 > 编程语言 > 正文

获取java.util.List的泛型类型

如何解决《获取java.util.List的泛型类型》经验,为你挑选了7个好方法。

我有;

List stringList = new ArrayList();
List integerList = new ArrayList();

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



1> BalusC..:

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

package test;

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

public class Test {

    List stringList = new ArrayList();
    List integerList = new ArrayList();

    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.
    }
}

您也可以为参数类型和返回方法类型执行此操作.

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


当然有一些情况下,这是非常有用的.例如,无配置的ORM框架.
..可以使用Class#getDeclaredFields()获取所有字段,而无需知道字段名称.

2> falstro..:

简答:不.

这可能是重复的,现在找不到合适的.

Java使用称为类型擦除的东西,这意味着在运行时两个对象都是等价的.编译器知道列表包含整数或字符串,因此可以维护类型安全的环境.此信息在运行时丢失(基于对象实例),列表仅包含"对象".

你可以找到一些关于类的信息,它可以通过参数化来获得什么类型,但通常这只是扩展"对象"的任何东西,即任何东西.如果将类型定义为

class  AClass {....}

AClass.class只包含参数A受MyClass限制的事实,但更重要的是,没有办法说明.



3> 小智..:

您也可以对方法参数执行相同的操作:

Type[] types = method.getGenericParameterTypes();
//Now assuming that the first parameter to the method is of type List
ParameterizedType pType = (ParameterizedType) types[0];
Class clazz = (Class) pType.getActualTypeArguments()[0];
System.out.println(clazz); //prints out java.lang.Integer



4> Mohsen Kashi..:

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

((Class)((ParameterizedType)field.getGenericType()).getActualTypeArguments()[0]).getSimpleName()



5> Aram Kochary..:

如果你需要获得返回类型的泛型类型,当我需要在返回a Collection然后访问其泛型类型的类中查找方法时,我使用了这种方法:

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.List;

public class Test {

    public List test() {
        return null;
    }

    public static void main(String[] args) throws Exception {

        for (Method method : Test.class.getMethods()) {
            Class returnClass = method.getReturnType();
            if (Collection.class.isAssignableFrom(returnClass)) {
                Type returnType = method.getGenericReturnType();
                if (returnType instanceof ParameterizedType) {
                    ParameterizedType paramType = (ParameterizedType) returnType;
                    Type[] argTypes = paramType.getActualTypeArguments();
                    if (argTypes.length > 0) {
                        System.out.println("Generic type is " + argTypes[0]);
                    }
                }
            }
        }

    }

}

这输出:

泛型类型是类java.lang.String



6> Steve K..:

集合的泛型类型应该只有它实际上有对象,对吧?所以不是更容易做到:

Collection myCollection = getUnknownCollectionFromSomewhere();
Class genericClass = null;
Iterator it = myCollection.iterator();
if (it.hasNext()){
    genericClass = it.next().getClass();
}
if (genericClass != null) { //do whatever we needed to know the type for

在运行时没有泛型类型的东西,但运行时内部的对象保证与声明的泛型相同,所以在处理它之前只需测试项的类就很容易了.


如果你有一个空集合?或者如果你有一个带有整数和字符串的Collection

7> ggb667..:

扩展Steve K的答案:

/** 
* Performs a forced cast.  
* Returns null if the collection type does not match the items in the list.
* @param data The list to cast.
* @param listType The type of list to cast to.
*/
static  List castListSafe(List data, Class listType){
    List retval = null;
    //This test could be skipped if you trust the callers, but it wouldn't be safe then.
    if(data!=null && !data.isEmpty() && listType.isInstance(data.iterator().next().getClass())) {
        @SuppressWarnings("unchecked")//It's OK, we know List contains the expected type.
        List foo = (List)data;
        return retval;
    }
    return retval;
}
Usage:

protected WhateverClass add(List data) {//For fluant useage
    if(data==null) || data.isEmpty(){
       throw new IllegalArgumentException("add() " + data==null?"null":"empty" 
       + " collection");
    }
    Class colType = data.iterator().next().getClass();//Something
    aMethod(castListSafe(data, colType));
}

aMethod(List foo){
   for(Foo foo: List){
      System.out.println(Foo);
   }
}

aMethod(List bar){
   for(Bar bar: List){
      System.out.println(Bar);
   }
}

推荐阅读
手机用户2502852037
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有