如何获取列表包含的元素类?

时间:2011-11-15 09:40:11

标签: java class list

我有一个这样的清单:

private List<T> myList = new ArrayList<T>();

我想得到T.的.class我怎么能这样做?

我的意思是:

myList.getClass()

修改 我试过了:

 Field genericField = Wrapper.class.getDeclaredField("myList");
 ParameterizedType genericType = (ParameterizedType) genericField.getGenericType();
 Class<?> genericClass = (Class<?>) genericType.getActualTypeArguments()[0];

当我调试它时

  

genericType

的值为:

  

的java.util.List

所以我认为这个问题肯定与此问题不同:Get generic type of java.util.List因为如果您使用T声明了一个类,并在稍后的另一个方法中为T分配了一些内容, T暂时消失。

4 个答案:

答案 0 :(得分:11)

你不能因为类型擦除。 泛型类型在运行时是未知的(它被'擦除'),它仅在编译时使用。

这是java泛型和c#泛型之间的主要区别。例如。

答案 1 :(得分:3)

为什么你需要知道这个?也许这会做你需要的事情

// must be at least one element (and all elements are the same)
Class elementType = myList.get(0).getClass(); 

要做到这一点的唯一方法是

  • 将类型存储在字段中,并为此添加getter方法。

private final Class<T> type;
private final List<T> list = new ArrayList<T>();

public Class<T> getType() { return type; }
  • 在实际字段上使用getGenericType(),假设参数类型不是通用的。
  • 使用具有特定类型的子类。

List list = new ArrayList<Integer>() { }; // create a specific sub-class
final Class<? extends List> listClass = list.getClass();
final ParameterizedType genericSuperclass = (ParameterizedType) listClass.getGenericSuperclass();
Class elementType = (Class) genericSuperclass.getActualTypeArguments()[0];

这样做的一个缺点是,您最终可能会创建大量匿名类,并可能会对ArrayList.class != list.getClass()之类的内容产生混淆,list instanceof ArrayList

答案 2 :(得分:1)

你做不到。该信息在运行时不可用。如果您的列表不为空,您可以通过检查第一个元素的类来逃避。

答案 3 :(得分:0)

只有当你的例子中暗示的列表是一个字段并且type参数是具体的而不是它本身是封闭类的类型参数(在你的例子中似乎是这种情况)时,这是唯一可能的。您只能通过反射获取字段的声明类型参数:

Field listField = Test.class.getDeclaredField("myList");
ParameterizedType listType= (ParameterizedType) listField.getGenericType();
Class contentClass = (Class) listType.getActualTypeArguments()[0];

不确定这是否完全正确,但你明白了 - 它相当复杂,因为类型参数可以是有界的和通配符。