I understand that in Java contrary to, for example, C# generics are compile-time feature and is removed via type erasure. So, how does Gson's TypeToken
really work? How does it get the generic type of an object?
TypeToken uses an anonymous class to ensure it keeps generic type information, instead of just creating an object. Show activity on this post. Now you can easily get Type parameters to super type (TypeToken) as specified above.
Class TypeToken<T> Represents a generic type T . Java doesn't yet provide a way to represent generic types, so this class does. Forces clients to create a subclass of this class which enables retrieval the type information even at runtime.
From §4.6 of the JLS (emphasis mine):
Type erasure is a mapping from types (possibly including parameterized types and type variables) to types (that are never parameterized types or type variables). We write |T| for the erasure of type T. The erasure mapping is defined as follows:
The erasure of a parameterized type (§4.5) G is |G|.
The erasure of a nested type T.C is |T|.C.
The erasure of an array type T[] is |T|[].
The erasure of a type variable (§4.4) is the erasure of its leftmost bound.
The erasure of every other type is the type itself.
Therefore, if you declare a class with an anonymous subclass of itself, it keeps it's parameterized type; it's not erased. Therefore, consider the following code:
import java.lang.reflect.ParameterizedType; import java.util.Arrays; import java.util.HashMap; public class Erasure<T> { public static void main(String...strings) { Class<?> foo = new Erasure<HashMap<Integer, String>>() {}.getClass(); ParameterizedType t = (ParameterizedType) foo.getGenericSuperclass(); System.out.println(t.getOwnerType()); System.out.println(t.getRawType()); System.out.println(Arrays.toString(t.getActualTypeArguments())); } }
This outputs:
null class Erasure [java.util.HashMap<java.lang.Integer, java.lang.String>]
Notice that you would get a ClassCastException
if you did not declare the class anonymously, because of erasure; the superclass would not be a parameterized type, it would be an Object
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With