The TypeToken usage approach will not work.
new TypeToken<ArrayList<T>>()
impossible due to how generics (type erasure) and reflection work. The whole TypeToken trick works because Class#getGenericSuperclass() does the following
Returns a type representing the direct superclass of the object (class, interface, primitive type, or void) represented by this class.
If the superclass is a parameterized type, the returned Type object must accurately reflect the actual type parameters used in the source code.
In other words, if he sees ArrayList<T> , then ParameterizedType returned, and you cannot retrieve the compile-time value that a variable of type T would have.
Type and ParameterizedType are both interfaces. You can provide an instance of your own implementation.
So, you have two options:
Option 1: Add java.lang.reflect.ParameterizedType yourself and pass it to Gson.
private static class ListParameterizedType implements ParameterizedType { private Type type; public ListParameterizedType(Type type) { this.type = type; } @Override public Type[] getActualTypeArguments() { return new Type[] {type}; } @Override public Type getRawType() { return ArrayList.class; } @Override public Type getOwnerType() { return null; }
Then just:
Type type = new ListParameterizedType(clazz); List<T> list = gson.fromJson(json, type);
Note that according to javadoc , the equals method must also be implemented.
Option 2: Parse the list manually, then use Gson for each item
public <T> List<T> listEntity(Class<T> clazz) throws WsIntegracaoException { try { // Consuming remote method String strJson = getService().listEntity(clazz.getName()); JsonParser parser = new JsonParser(); JsonArray array = parser.parse(strJson).getAsJsonArray(); List<T> lst = new ArrayList<T>(); for(final JsonElement json: array){ T entity = GSON.fromJson(json, clazz); lst.add(entity); } return lst; } catch (Exception e) { throw new WsIntegracaoException( "WS method error [listEntity()]", e); } }