How to Get class of Elements that List Contains?

前端 未结 4 379
醉梦人生
醉梦人生 2021-01-18 01:47

I have a list like that:

private List myList = new ArrayList();

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

相关标签:
4条回答
  • 2021-01-18 02:09

    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.

    0 讨论(0)
  • 2021-01-18 02:15

    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

    0 讨论(0)
  • 2021-01-18 02:16

    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.

    0 讨论(0)
  • 2021-01-18 02:24

    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.

    0 讨论(0)
提交回复
热议问题