【问题标题】:How can I determine the unerased type of a field?如何确定字段的未擦除类型?
【发布时间】:2016-04-08 16:27:24
【问题描述】:

我有一个通用的响应包装类:

public class Response <T> {
    T response;
}

以及要包装的无关类:

public class ServiceResponse {
    String someField;
}

当我提出服务请求时,我会收到类似于以下内容的 JSON 响应:

{ "code":200, "response":{"someField":"some text"} }

现在,我所有的服务响应都有相同的外包装,也就是说,它们都有:

{ "code":200, "timestamp":"....", "response":... }

但响应字段的实际格式/类型对于每个服务请求是不同的。当我反序列化响应时,我需要知道response 字段的类型,以便我可以创建适当的实例,如果反序列化是在Response 内完成的,我可以使用:

response = new T(jsonParser);

但是,我在一个由反射驱动的库中完成所有这些工作,因此我通常使用以下代码反序列化整个树:

wrapper = deserializer.parseObject(Response<ServiceResponse>.class)

但是,此时我的 parseObject 方法无法正确确定 T 的类型。

我可以使用类似的东西:

Response<ServiceResponse> response = new Response<>();
Field field = response.getClass().getDeclaredField("response");
Type type = field.getGenericType();

然后告诉我responseT 类型,但我真正需要的是ServiceResponse

根据this SO question,我尝试转换为ParameterizedType,但这实际上似乎适用于Response&lt;ServiceResponse&gt; 类型的字段,而不是其中的实际字段(它失败了,因为type 不能转换为@ 987654337@)

有没有办法确定(在运行时)response 的原始类型?

最终,我可能不得不创建一个注释,提供有关如何反序列化字段的更多详细信息,可能是通过提供一个函数来执行此操作,但我更喜欢更透明的方法。

另一种可能性可能是在初始化时将 T 的 void 实例实际分配给响应,然后我可以从中获取实际类型...

【问题讨论】:

  • 简短回答:不。长答案:提供有关您如何使用Response 的更多详细信息。您尝试获取Field 的小sn-p 具有误导性,因为这样做没有意义,您已经知道您有ServiceResponse。你如何得到你的Response&lt;?&gt;
  • 提供了有关用例的更多信息,但基本上我试图从网络服务请求中反序列化 Response&lt;?&gt;。在外层我知道什么?是,但在反序列化代码中我没有,所以我试图从可用的反射信息中恢复它。
  • 是的,恐怕您的简短回答可能是实际答案,因为泛型确实是一种方便的编译器虚构。
  • 那我有点糊涂了。如果在外层您知道? 是什么,那么只需将其提供给反序列化代码即可。如果在编译时你知道你想要一个Response&lt;ServiceResponse&gt;,那么只需将ServiceResponse.class 传递给它,你就不需要(你不能,真的)从Response 中检索它。在反序列化代码中,另一种方法是在反序列化策略的 JSON 中指示。 Jackson 有时会使用类似 @class 的字段,并将完全限定的目标类名称作为其值。
  • ServiceResponse 传递给反序列化将需要针对这种特定情况进行专门化。我正在寻找一个通用的解决方案,它允许我使用:deserialize(Foo&lt;X, Y, Z...&gt;.class),它可以正确地实例化 Foo 对象中具有适当类型的任何字段。

标签: java reflection


【解决方案1】:

查看这篇文章: http://mydailyjava.blogspot.com/2013/06/advanced-java-generics-retreiving.html

它实际上正是您正在寻找的。​​p>

据此,您只需要扩展您的 Response 类,然后查询其超类的泛型。

【讨论】:

  • @Marco13,你是对的,但我不习惯从博客文章中剪切和粘贴代码
  • 当然(我不是反对者,顺便说一句),但也许在这里插入这个链接作为评论就足够了......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多