我需要将JSON对象数组解析为列表。我会通过
Class<?> classToParse
作为参数。根据{{3}},我需要像
这样的东西Type listType = new TypeToken<List<ExampleClass>>() {}.getType();
与
一起使用 gsonInstance.fromJson(output, listType);
但是如何指定我的&#34; classToParse&#34; (参数)而不是硬编码的ExampleClass?我无法按原样插入。
答案 0 :(得分:0)
您无法使用运行时调用替换编译类型的type参数 - 类型信息以及类型参数由Java编译器在编译时生成。
首先请注意如何声明 Gson.fromJson(...)
重载:既没有使用TypeToken
作为参数,但是他们可以接受Type
- 这很好,因为TypeToken
是不必须解析参数化类型JSON,类型只是重要的。其次,非常好将现成的Type
个实例传递给fromJson
方法:
final Foo foo = gson.fromJson(..., Foo.class);
final List<Foo> foos = gson.fromJson(..., new TypeToken<List<Foo>>(){}.getType());
请注意,在两个案例中都会传递文字:第二个文字只会更长,并且每次执行该行时都会创建。 Type
接口不提供任何mutator方法,因此您可以将其视为可以视为常量的东西(以及其他值类型ilke String
s,Integer
和等等):
static final TypeToken<List<Foo>> fooListTypeToken = new TypeToken<List<Foo>>(){};
...
final List<Foo> foos = gson.fromJson(..., fooListTypeToken.getType());
甚至更短(但我更喜欢以前的方式 - 我会向你推荐[你可以重复使用类型令牌而不会失去它]):
static final Type fooListType = new TypeToken<List<Foo>>(){}.getType();
...
final List<Foo> foos = gson.fromJson(..., fooListTypeToken);
fooListTypeToken
和Foo.class
与程序化观点有多大差异?嗯,基本上没有区别(除了第一个代表一个列表,而后者代表一个具体的类,当然)。两者都是价值观。
但是,如果您希望获得任何必须原因的给定元素类(或更好的类型)的动态类型,那么您可以自己创建Type
个实例并只传递它们到fromJson
:
static ParameterizedType createJavaUtilListParameterizedType(final Type elementType) {
return new ParameterizedType() {
@Override
public Type getRawType() {
return List.class;
}
@Override
public Type[] getActualTypeArguments() {
return new Type[]{ elementType };
}
@Override
public Type getOwnerType() {
return null;
}
};
}
该方法只创建ParameterizedType
的匿名实现,其中:
getRawType()
- 必须返回java.util.List.class
,容器参数化类型getActualTypeArguments()
- 必须返回元素类型;请注意,它总是必须返回一个新数组,以免在别处被损坏(因为它不是0长度数组)getOwnerType()
- 在这种情况下未实现,可以安全地返回null
。所以现在替换在运行时可用:
final List<Foo> foos = gson.fromJson(..., createJavaUtilListParameterizedType(Foo.class));
但
final List<Foo> foos = gson.fromJson(..., createJavaUtilListParameterizedType(new TypeToken<GenericElement<String, Integer>>(){}.getType()));
用于参数化类型。好吧,与保持static final
对类型标记的引用以及稍后从中提取类型相比仍然没有太大差别。从语义上讲,它与编译器在编译时的作用相同。
Gson TypeToken
还提供static TypeToken<?> getParameterized(Type rawType, Type... typeArguments)
,可以使用static ParameterizedType createJavaUtilListParameterizedType(final Type elementType) {
return (ParameterizedType) TypeToken.getParameterized(List.class, elementType).getType();
}
代替自己实现的参数化类型,如:
class Dog
attr_accessor :name
def initialize()
@name = "Denver"
end
end
def rename_dog(dog)
dog.name = "New_Dog_Name"
return
end
dog = Dog.new
puts "Dog's initial name: #{dog.name}" # => Dog's initial name: Denver
rename_dog(dog)
puts "Dog's New name: #{dog.name}" # => Dog's New name: New_Dog_Name