Java Gson TypeToken是如何工作的?

Java Gson TypeToken是如何工作的?,java,generics,gson,erasure,Java,Generics,Gson,Erasure,我知道在Java中,C#泛型是编译时特性,通过类型擦除删除。那么,Gson的TypeToken到底是如何工作的呢?它是如何获得对象的通用类型的?Java的类型擦除适用于单个对象,而不是类、字段或方法。TypeToken使用匿名类来确保它保留泛型类型信息,而不仅仅是创建一个对象。 (我的重点): 类型擦除是从类型(可能包括参数化类型和类型变量)到类型(从未参数化类型或类型变量)的映射。我们为类型T的擦除写入| T |。擦除映射定义如下: 参数化类型(§4.5)G的擦除为| G | 嵌套类型T.C的

我知道在Java中,C#泛型是编译时特性,通过类型擦除删除。那么,Gson的
TypeToken
到底是如何工作的呢?它是如何获得对象的通用类型的?

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

(我的重点):

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

参数化类型(§4.5)G的擦除为| G |

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

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

类型变量(§4.4)的删除是对其最左边边界的删除

其他类型的擦除就是类型本身。

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

import java.lang.reflect.ParameterizedType;
import java.util.Arrays;
import java.util.HashMap;

public class Erasure<T>
{
    public static void main(String...strings) {
      Class<?> foo = new Erasure<HashMap<Integer, String>>() {}.getClass();
      ParameterizedType t = (ParameterizedType) foo.getGenericSuperclass();
      System.out.println(t.getOwnerType());
      System.out.println(t.getRawType());
      System.out.println(Arrays.toString(t.getActualTypeArguments()));
    }
}
import java.lang.reflect.ParameterizedType;
导入java.util.array;
导入java.util.HashMap;
公共类擦除
{
公共静态void main(字符串…字符串){
类foo=newerasure(){}.getClass();
ParameteredType t=(ParameteredType)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<java.lang.Integer, java.lang.String>]
null
类擦除
[java.util.HashMap]
请注意,如果由于擦除而没有匿名声明类,则会得到一个
ClassCastException
;超类将不是参数化类型,而是一个
对象