Gson TypeToken如何工作? [英] How does Gson TypeToken work?

查看:106
本文介绍了Gson TypeToken如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我明白在Java中与C#泛型相反,例如,C#泛型是编译时功能,并通过类型擦除来删除。那么,Gson的 TypeToken 真的有效吗?它是如何获得对象的泛型类型的?

解决方案



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

< blockquote>

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

擦除参数化类型(§4.5)G是| G |。



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

删除一个数组类型T []是删除一个类型变量(§4.4)是删除它的最左边界。



删除其他类型的类型本身。

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

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

公共类擦除< 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()));


$ / code $ / pre
$ b $ p

这个输出:

  null 
class Erasure
[java.util.HashMap< java.lang.Integer,java.lang.String>]

请注意,如果您没有收到 ClassCastException 匿名宣布班级,因为删除;超类不会是参数化类型,它会是 Object


I understand that in Java contrary to, for example, C# generics are compile-time feature and is removed via type erasure. So, how does Gson's TypeToken really work? How does it get the generic type of an object?

解决方案

From §4.6 of the JLS (emphasis mine):

Type erasure is a mapping from types (possibly including parameterized types and type variables) to types (that are never parameterized types or type variables). We write |T| for the erasure of type T. The erasure mapping is defined as follows:

The erasure of a parameterized type (§4.5) G is |G|.

The erasure of a nested type T.C is |T|.C.

The erasure of an array type T[] is |T|[].

The erasure of a type variable (§4.4) is the erasure of its leftmost bound.

The erasure of every other type is the type itself.

Therefore, if you declare a class with an anonymous subclass of itself, it keeps it's parameterized type; it's not erased. Therefore, consider the following code:

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()));
    }
}

This outputs:

null
class Erasure
[java.util.HashMap<java.lang.Integer, java.lang.String>]

Notice that you would get a ClassCastException if you did not declare the class anonymously, because of erasure; the superclass would not be a parameterized type, it would be an Object.

这篇关于Gson TypeToken如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆