I have this code:
Type typeOfObjectsList = new TypeToken>() {}.getType();
List objectsList = new Gson().fromJso
The syntax you are proposing is invalid. The following
new TypeToken<ArrayList<Class.forName(MyClass)>>
is invalid because you're trying to pass a method invocation where a type name is expected.
The following
new TypeToken<ArrayList<T>>()
is not possible because of how generics (type erasure) and reflection works. The whole TypeToken
hack works because Class#getGenericSuperclass()
does the following
Returns the Type representing the direct superclass of the entity (class, interface, primitive type or void) represented by this Class.
If the superclass is a parameterized type, the Type object returned must accurately reflect the actual type parameters used in the source code.
In other words, if it sees ArrayList<T>
, that's the ParameterizedType
it will return and you won't be able to extract the compile time value that the type variable T
would have had.
Type
and ParameterizedType
are both interfaces. You can provide an instance of your own implementation.
You can do this with Guava's more powerful TypeToken:
private static <T> Type setModelAndGetCorrespondingList2(Class<T> type) {
return new TypeToken<ArrayList<T>>() {}
.where(new TypeParameter<T>() {}, type)
.getType();
}
sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
workes. No need for custom implementation
Type type = ParameterizedTypeImpl.make(List.class, new Type[]{childrenClazz}, null);
List list = gson.fromJson(json, type);
Can be used with maps and any other collection:
ParameterizedTypeImpl.make(Map.class, new Type[]{String.class, childrenClazz}, null);
Here is nice demo how you can use it in custom deserializer: Deserializing ImmutableList using Gson