How to Get class of Elements that List Contains?

梦想与她 提交于 2020-01-21 11:05:44

问题


I have a list like that:

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

I want to get the .class of T. How can I do that?

I mean as like:

myList.getClass()

EDIT: I tried that:

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

and when I debug it

genericType

has a value of:

java.util.List

so I think that this is certainly different issue from that question: Get generic type of java.util.List because of if you declare a class with T and assign something to T later at another method, class that T holds disappear.


回答1:


You can't because of type erasure. The generic type is not known at runtime (it's 'erased'), it's only used at compile time.

This is a major difference between java generics and c# generics for example.




回答2:


Why do you need to know this? Perhaps this will do what you need

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

The only way to do this is to either

  • store the type in a field and add a getter method for this.

like

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

public Class<T> getType() { return type; }
  • use getGenericType() on the actual field, assuming the parameter type is NOT generic.
  • use a sub class with a specific type.

like

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];

This has the dis-advantage that you could end up creating lots of anonymous classes and potential confusion with things like ArrayList.class != list.getClass() however list instanceof ArrayList




回答3:


You cannot. That information is not available at runtime. If your list isn't empty you might be able to get away with checking the class of the first element.




回答4:


This is only possible if the list, as implied in your example, is a field AND the type parameter is concrete rather than itself being a type parameter of the enclosing class (which seems to be the case in your example), and you can only get the declared type parameter for the field via reflection:

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

Not sure if this is entirely correct, but you get the idea - it's rather complex because type parameters can be bounded and wildcards.



来源:https://stackoverflow.com/questions/8134251/how-to-get-class-of-elements-that-list-contains

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!