我有一个HTTP请求处理程序,它返回一个Sub FilterCstomers()
Dim f As String: f = InputBox("Type the text you want to filter:")
With Sheets("Customers Pivot").PivotTables("Customers_PivotTable")
.ClearAllFilters
.PivotFields("Concatenation for filtering").CurrentPage = "*f*"
End With
End Sub
反序列化的JSON,它派生自一个抽象Object
,然后转换为正确的类。我有一些问题使这个处理程序返回Request
。
List
如果public class ListMyResource extends AbstractRequest
{
public boolean isCollection;
public ListTransactions()
{
this.isCollection = true;
}
public final RequestMethod REQUEST_METHOD = RequestMethod.GET;
public final String URL_METHOD = "";
public Class<ArrayList<MyResource>> getResourceClass()
{
return new ArrayList<MyResource>().getClass();
}
}
public Object getDeserializedResponse()
{
Response response = new Response(this.request, true);
try
{
if (this.request.isCollection())
{
List<this.request.getResourceClass()> list = new ArrayList<this.request.getResourceClass()>();
listType = new TypeToken<ArrayList<AbstractObject>>() { }.getType();
response.setData(deserialize.fromJson(this.getResponse(), listType));
}
else
{
response.setData(deserialize.fromJson(this.getResponse(), this.request.getClazz()));
}
}
catch (JsonSyntaxException jse)
{
MyLibrary.LOG.error("Could not parse JSON", jse);
response.setRequestWasSuccessfull(false);
}
return response;
}
返回false,并且该方法只需要提供一个反序列化的对象,上面的代码就可以正常工作,但它不能用于集合,因为我无法将结果放在来自列表中isCollection()
的{{1}}。这导致getResourceClass()
。我如何处理这个问题,以便达到预期的效果?
答案 0 :(得分:1)
ArrayList<this.request.getResourceClass()>
这不起作用。 Java类型参数必须是编译时&#34;常量&#34; (我的意思是,编译器已知的东西)。所以,
List<String> strings
是类型参数的有效语法,但
List<some.runtime.expression.here()>
不是。接下来,我强烈建议您不要使用Class<?>
来传递数据类型信息。请注意,Class<?>
包含有关系统中真实类型的信息。考虑你想要一个字符串列表,一个整数列表和一个布尔类型列表。你不能ArrayList<String>.class
- 它是Java中的非法表达,因为实际的类型参数不是类信息的一部分。你能用ArrayList
之类的东西继承extends ArrayList<String>
吗?你可以,但你不应该。如果子类的类别为final
或您要使用LinkedList
怎么办?某种代码臃肿,不是吗?
Class
为java.lang.reflect.Type
,Gson要求将后者的实例传递给fromJson()
方法。如果你自己构建它怎么办? Gson提供了一种方便的机制来构造java.lang.reflect.Type
和java.lang.reflect.ParameterizedType
(后者在Gson中非常集中地用于集合,详见Gson TypeToken s)。有两种方式:
TypeToken.getParameterized(rawType, typeParameter1, typeParameter2)
例如,TypeToken.getParameterized(List.class, String.class).getType()
将返回ParameterizedType
实例,就像您可以编写List<String>.class
一样。这是一种真正的动态方法,您可以将一些运行时执行结果传递给getParameterized()
方法。
TypeToken
子类化这里的诀窍是TypeToken
是一个抽象类,它可以参数化,让Gson在运行时分析一个通常是匿名的类来获取实际参数,让getType()
方法返回一个编译时组合类型:new TypeToken<List<String>>(){}.getType()
(子类可以存储有关其超类参数化的信息,Gson在运行时使用它)。请注意,getRawType
仅返回List.class
- 这就是Java泛型的实现方式,因为Class
无法存储实际的类型参数(请阅读Java generics and erasure的更多信息)。
考虑到这个模糊的解释,只需重构您的getDeserializedResponse()
方法,使请求返回java.lang.reflect.Type
而不是Class<?>
。我甚至认为您可以从该方法中删除isCollection
并让Gson自行完成所有操作:Gson 可以区分List<String>
和List<Integer>
类型。