Gson TypeToken如何运作?

据我所知,在Java中,例如,C#generics是编译时function,并通过类型擦除删除。 那么,Gson的TypeToken如何真正起作用? 它是如何获得对象的generics类型的?

这是一招!

从JLS的§4.6 (强调我的):

类型擦除是从类型(可能包括参数化类型和类型变量)到类型(从不参数化类型或类型变量)的映射。 我们写| T | 对于类型T的擦除。擦除映射定义如下:

参数化类型(第4.5节)G的擦除是| G |。

嵌套类型TC的擦除是| T | .C。

数组类型T []的擦除是| T | []。

类型变量(第4.4节)的擦除是其最左边界的擦除。

每种其他类型的擦除都是类型本身。

因此,如果您声明一个具有自己的匿名子类的类,它将保持其参数化类型; 它没有被删除。 因此,请考虑以下代码:

 import java.lang.reflect.ParameterizedType; import java.util.Arrays; import java.util.HashMap; public class Erasure { public static void main(String...strings) { Class foo = new Erasure>() {}.getClass(); ParameterizedType t = (ParameterizedType) foo.getGenericSuperclass(); System.out.println(t.getOwnerType()); System.out.println(t.getRawType()); System.out.println(Arrays.toString(t.getActualTypeArguments())); } } 

这输出:

 null class Erasure [java.util.HashMap] 

请注意,如果由于擦除而未匿名声明该类,则会出现ClassCastException ; 超类不是参数化类型,它将是一个Object

Java的类型擦除适用于单个对象,而不是类或字段或方法。 TypeToken使用匿名类来确保它保留generics类型信息,而不是仅创建对象。