Why I have to define a subclass to get the Type of superclass' generic param? Is the limit necessary?
I read the code of Fastjson of Alibaba and tried to figure out why use TypeReference must create an anonymous subclass. Then I found that an object cannot get its own generic param Type even its own Type.
public class TypeReference {
static ConcurrentMap<Type, Type> classTypeCache
= new ConcurrentHashMap<Type, Type>(16, 0.75f, 1);
protected final Type type;
protected TypeReference() {
Type superClass = getClass().getGenericSuperclass();
Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
Type cachedType = classTypeCache.get(type);
if (cachedType == null) {
classTypeCache.putIfAbsent(type, type);
cachedType = classTypeCache.get(type);
}
this.type = cachedType;
}
// ...
}
Sorry for my poor English. Thanks for your answers.
Because of Type Erasure.
Consider the following example
This will print
true. Regardless of the generic type, both instances ofArrayListhave the same class and a singleClassobject. So how could this singleClassobject return the rightTypefor both objects?We can even get a step further,
Objects do not know their generic type. If a collection is immutable and always empty, it can be used to represent arbitrary empty lists. The same applies to stateless functions
Prints
true(on most systems; this is not a guaranteed behavior).Generic types are only retained in some specific cases, like the signatures of field and method declarations and generic super types.
That’s why you need to create a subclass to exploit the fact that it will store the declared generic supertype. While it sometimes would be useful to construct a
Typeinstance in a simpler way and a suitable factory method can be regarded a missing feature, getting the actual generic type of an arbitrary object (or itsClass) is not possible in general.