How to get type arguments class of generic method

2020-07-26 07:31发布

问题:

How to get the type argument of an argument passed to a method ? For example I have

List<Person> list = new ArrayList<Person>(); 

public class Datastore {

  public <T> void insert(List<T> tList) {
     // when I pass the previous list to this method I want to get Person.class ; 
  }
} 

回答1:

Due to type erasure, the only way you can do it is if you pass the type as an argument to the method.

If you have access to the Datastore code and can modify you can try to do this:

public class Datastore {
    public T void insert(List<T> tList, Class<T> objectClass) {
    }
}

and then call it by doing

List<Person> pList = new ArrayList<Person>();
...
dataStore.insert(pList, Person.class);

Every response I've seen to this type of question was to send the class as a parameter to the method.



回答2:

Due to Type Erasure I doubt whether we can get it, barring some reflection magic which might be able to do it.

But if there are elements inside the list, we can reach out to them and invoke getClass on them.



回答3:

You can try this ...

if(tList != null && tList.size() > 0){
    Class c = tList.get(0).getClass();
}


回答4:

I think you can't do that. Check out this class:

public class TestClass
{
    private List<Integer> list = new ArrayList<Integer>();

    /**
     * @param args
     * @throws NoSuchFieldException
     * @throws SecurityException
     */
    public static void main(String[] args)
    {
        try
        {
            new TestClass().getClass().getDeclaredField("list").getGenericType(); // this is the type parameter passed to List
        }
        catch (SecurityException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (NoSuchFieldException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        new TestClass().<Integer> insert(new ArrayList<Integer>());
    }

    public <T> void insert(List<T> tList)
    {
        ParameterizedType paramType;
        paramType = (ParameterizedType) tList.getClass().getGenericInterfaces()[0];
        paramType.getActualTypeArguments()[0].getClass();
    }
}

You can get the type parameters from a class or a field but it is not working for generic methods. Try using a non-generic method!

OR

another solution might be passing the actual Class object to the method.