Как работает Gson TypeToken?

Я понимаю, что в Java, в отличие, например, от дженериков C#, функция времени компиляции и удаляется с помощью стирания типа. Итак, как на самом деле работает TypeToken от Gson? Как он получает общий тип объекта?


person Heisenberg    schedule 02.05.2015    source источник


Ответы (2)


Это трюк!

Из §4.6 JLS (выделено мной):

Стирание типов — это сопоставление типов (возможно, включая параметризованные типы и переменные типов) в типы (которые никогда не являются параметризованными типами или переменными типов). Пишем |Т| для стирания типа 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()));
    }
}

Это выводит:

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

Обратите внимание, что вы получите ClassCastException, если не объявите класс анонимно из-за стирания; суперкласс не будет параметризованным типом, это будет Object.

person durron597    schedule 02.05.2015

Стирание типов в Java применяется к отдельным объектам, а не к классам, полям или методам. TypeToken использует анонимный класс, чтобы гарантировать, что он хранит информацию об универсальном типе, а не просто создает объект.

person Louis Wasserman    schedule 02.05.2015