Java Gson TypeToken是如何工作的?
我知道在Java中,C#泛型是编译时特性,通过类型擦除删除。那么,Gson的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的
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
;超类将不是参数化类型,而是一个对象