I have this code, which compiles:
new TypeToken<ArrayList<ServerTask>>() {}.getType()
Then I have tried
ArrayList<ServerTask>.class
which does not compile.
I am new to Java programming (came from C#) and I have thought that T.class
is an exact equivalent of typeof(T)
in C#. Apparently there is something really basic that I do not understand, so my question is what is wrong with ArrayList<ServerTask>.class
and do I have no choice, but use new TypeToken<ArrayList<ServerTask>>() {}.getType()
instead? Is there a shorter (nicer, saner) form?
Thanks.
Unfortunately (?) Java implements generics using Type Erasure.
This means that there is no construct to get the generic type, and at runtime your ArrayList actually only stores Objects.
To be exact, Generics in Java are a compile-time only construct. They guarantee type-safety at compile time only.
EDIT: I just noticed this bit of code -
new TypeToken<ArrayList<ServerTask>>() {}.getType()
This is a workaround for the limitations of type erasure. Type information is preserved if you extend a generic class with a specific type. For example:
public interface List<T> {
}
public class StringList implements List<String> {
// The bytecode of this class contains type information.
}
In your example, you are trivially extending the class TypeToken
, causing the compiler to generate an anonymous inner class that contains the type information. The implementation of TypeToken.getType()
will use reflection to give you this type information.
EDIT2: For a more detailed explanation, have a look at Reflecting Generics.
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