I'm active on Stack Overflow, and often see questions with code more or less like this:
public class Main {
public static void main(String[] args) {
// should work right?
MyClass mc = new Gson().fromJson("{}", Main.<MyClass>typeTokenHelper());
}
static class MyClass {}
public static <T> Type typeTokenHelper() {
return new TypeToken<T>() {}.getType();
}
}
Of course this fails with:
java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to test.Main$MyClass
Since there is not actually any type information available from the TypeToken. The Type that you get is the generic type T:
Type t = Main.<MyClass>typeTokenHelper();
System.out.println(t); // prints 'T'. instead of the naïvely expected 'MyClass'
This is confusing. The missing type information should not be silently ignored only to get a ClassCastException later. The missing type information is caused by a design time error and should be flagged as early as possible.
At first glance a check like this:
// where 'typeOfT' is the type returned by TypeToken::getType
if(typeOfT instanceof TypeVariable) { // java.lang.reflect.TypeVariable
throw new RuntimeExcepiton(...);
}
Somewhere might fix this issue. Perhaps in TypeToken::getSuperclassTypeParameter or in Gson::fromJson. (I don't know where the use of TypeTokens with TypeVariables might be required though)
I'm active on Stack Overflow, and often see questions with code more or less like this:
Of course this fails with:
Since there is not actually any type information available from the
TypeToken. TheTypethat you get is the generic typeT:This is confusing. The missing type information should not be silently ignored only to get a
ClassCastExceptionlater. The missing type information is caused by a design time error and should be flagged as early as possible.At first glance a check like this:
Somewhere might fix this issue. Perhaps in
TypeToken::getSuperclassTypeParameteror inGson::fromJson. (I don't know where the use of TypeTokens with TypeVariables might be required though)