type fromjson from and java generics gson erasure

fromjson - java gson to list



¿Cómo funciona Gson TypeToken? (2)

El borrado de tipo de Java se aplica a objetos individuales, no a clases, campos o métodos. TypeToken usa una clase anónima para asegurarse de que mantiene información de tipo genérico, en lugar de solo crear un objeto.

Entiendo que en Java, a diferencia de, por ejemplo, los genéricos de C # son funciones de tiempo de compilación y se eliminan mediante el borrado de tipo. Entonces, ¿cómo funciona realmente TypeToken de Gson? ¿Cómo se obtiene el tipo genérico de un objeto?


A partir del §4.6 del JLS (énfasis mío):

El borrado de tipo es una asignación de tipos (que posiblemente incluya tipos parametrizados y variables de tipo) a tipos (que nunca son tipos parametrizados o variables de tipo). Nosotros escribimos | T | para el borrado de tipo T. El mapeo de borrado se define de la siguiente manera:

El borrado de un tipo parametrizado (§4.5) G es | G |.

El borrado de un tipo anidado TC es | T | .C.

El borrado de un tipo de matriz T [] es | T | [].

El borrado de una variable de tipo (§4.4) es el borrado de su límite más a la izquierda.

El borrado de cualquier otro tipo es el tipo en sí.

Por lo tanto, si declara una clase con una subclase anónima de sí misma, mantendrá su tipo parametrizado; no se borra Por lo tanto, considere el siguiente código:

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

Esto produce:

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

Tenga en cuenta que obtendría una ClassCastException si no declarara la clase de forma anónima, debido a un borrado; La superclase no sería un tipo parametrizado, sería un Object .