为什么在这个语句中使用{}来实例化,Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();
Why {} is used in this statement for instantiation, Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();
请解释为什么 {}
在
中使用
Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();
这来自 Gson 文档 link to documentation
它正在创建一个新的匿名类型。这是类型擦除的解决方法,因为如果 class 不是泛型 (*),您可以通过 Class.getGenericSuperclass()
和 Class.getGenericInterfaces()
反射性地获取 Collection<Integer>
。
这段代码基本上实现了相同的功能Ideone demo:
abstract class TypeToken<T> {
Type getType() {
ParameterizedType t = (ParameterizedType) getClass().getGenericSuperclass();
return t.getActualTypeArguments()[0];
}
}
public static void main (String[] args) {
Collection<Integer> list = new ArrayList<>();
System.out.println(list.getClass().getGenericInterfaces()[0]);
TypeToken<Collection<Integer>> tt = new TypeToken<Collection<Integer>>() {};
System.out.println(tt.getClass().getGenericSuperclass());
System.out.println(tt.getType());
}
输出:
java.util.List<E>
Ideone.Ideone$TypeToken<java.util.Collection<java.lang.Integer>>
java.util.Collection<java.lang.Integer>
您可以看到 Collection
的 "Integer"-ness 丢失了;但它仍然存在于 TypeToken
中,因此您可以通过 getType()
方法获取它。
(*) 这里很重要的一点是您不能(正确地)在泛型方法中创建 TypeToken
。例如:
<T> TypeToken<T> getGenericToken() {
return new TypeToken<T>() {};
}
不会像您预期的那样工作 Ideone demo。
TypeToken<Collection<String>> t = getGenericToken();
System.out.println(t.getType()); // T, not Collection<String>.
请解释为什么 {}
在
Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();
这来自 Gson 文档 link to documentation
它正在创建一个新的匿名类型。这是类型擦除的解决方法,因为如果 class 不是泛型 (*),您可以通过 Class.getGenericSuperclass()
和 Class.getGenericInterfaces()
反射性地获取 Collection<Integer>
。
这段代码基本上实现了相同的功能Ideone demo:
abstract class TypeToken<T> {
Type getType() {
ParameterizedType t = (ParameterizedType) getClass().getGenericSuperclass();
return t.getActualTypeArguments()[0];
}
}
public static void main (String[] args) {
Collection<Integer> list = new ArrayList<>();
System.out.println(list.getClass().getGenericInterfaces()[0]);
TypeToken<Collection<Integer>> tt = new TypeToken<Collection<Integer>>() {};
System.out.println(tt.getClass().getGenericSuperclass());
System.out.println(tt.getType());
}
输出:
java.util.List<E>
Ideone.Ideone$TypeToken<java.util.Collection<java.lang.Integer>>
java.util.Collection<java.lang.Integer>
您可以看到 Collection
的 "Integer"-ness 丢失了;但它仍然存在于 TypeToken
中,因此您可以通过 getType()
方法获取它。
(*) 这里很重要的一点是您不能(正确地)在泛型方法中创建 TypeToken
。例如:
<T> TypeToken<T> getGenericToken() {
return new TypeToken<T>() {};
}
不会像您预期的那样工作 Ideone demo。
TypeToken<Collection<String>> t = getGenericToken();
System.out.println(t.getType()); // T, not Collection<String>.