I think there is no way to implement what you want in a universal style using the TypeToken approach. In fact, note that to use type tokens, you must create an anonymous inner class. By doing this, you actually create a new class file whose supertype is confirmed as List<Article> . In other words, as if you had the following declaration:
class ArticleToken extends TypeToken<List<Article>> { ... }
If you write the above expression yourself, you will notice that the classfile ArticleToken.class tracks the common supertype in the so-called Signature attribute (see JVMS ). Therefore, this trick allows you to access this universal supertype later by calling Class.getGenericSupertype . In other words, this is an idiom for faking modified generics.
If you turn your code into a general method and replace the article with a variable of type T, what happens is that the type marker you created looks like this:
class GenericToken extends TypeToken<List<T>> { ... }
So, the information about T is stored as it is in the class file, and if reflectiopn asks for a general supertype of type marker, you just get TypeToken<List<T>> back, not TypeToken<List<Article>> , as you expected, which then calls the problem you see. What you need to do this work is true generalized generalizations, where binding T to an article on the method invocation site will affect the behavior of the new TypeToken<List<T>> , but unfortunately this is not the case as in Java case that uses erasable generics.
Maurizio Cimadamore
source share