如何在自定义Json反序列化器中获取通配符<?>的Class对象?
获取CustomDeserializer中<?>的Class对象方案
首先得明确:Java的泛型是类型擦除的,运行时JVM会把<NodeRpcResponseList<?>>里的通配符?擦除掉,所以没法直接从CustomDeserializer类本身拿到这个未知类型的Class对象。你需要通过以下两种常见方式来保留并获取这个类型信息:
方案1:将CustomDeserializer改为泛型类,显式传递类型
把你的反序列化器改成带泛型参数的类,在实例化时传入目标类型的Class对象,这样内部就能直接使用了:
public class CustomDeserializer<T> implements JsonDeserializer<NodeRpcResponseList<T>> { private final Class<T> elementType; // 构造方法传入目标类型的Class public CustomDeserializer(Class<T> elementType) { this.elementType = elementType; } @Override public NodeRpcResponseList<T> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { // 这里就可以直接使用elementType来做反序列化操作了 // 比如:T element = ctxt.readValue(p, elementType); // ... 你的业务逻辑 return null; } }
使用的时候,你需要明确指定泛型参数并传入对应的Class:
CustomDeserializer<YourConcreteType> deserializer = new CustomDeserializer<>(YourConcreteType.class);
方案2:通过反射解析类的泛型接口(适用于子类/匿名类明确指定泛型的场景)
如果你的CustomDeserializer是被某个明确指定了泛型参数的子类或匿名内部类实例化的,可以通过反射从类的泛型接口声明中提取类型参数:
public class CustomDeserializer implements JsonDeserializer<NodeRpcResponseList<?>> { private final Class<?> elementType; public CustomDeserializer() { // 获取当前类实现的泛型接口 Type genericInterface = getClass().getGenericInterfaces()[0]; if (genericInterface instanceof ParameterizedType) { // 拿到JsonDeserializer的泛型参数:NodeRpcResponseList<?> Type responseListType = ((ParameterizedType) genericInterface).getActualTypeArguments()[0]; if (responseListType instanceof ParameterizedType) { // 拿到NodeRpcResponseList的泛型参数:?对应的实际类型 Type elementType = ((ParameterizedType) responseListType).getActualTypeArguments()[0]; // 将Type转为Class(注意:仅适用于简单类,复杂泛型如List<String>会失效) this.elementType = (Class<?>) elementType; } else { throw new IllegalArgumentException("NodeRpcResponseList的泛型参数不是具体类型"); } } else { throw new IllegalArgumentException("当前类未使用泛型接口实例化"); } } @Override public NodeRpcResponseList<?> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { // 使用elementType进行反序列化 // ... return null; } }
但这个方案有个限制:必须通过明确指定泛型参数的子类或匿名类来实例化,比如:
// 匿名类明确指定具体泛型参数 JsonDeserializer<NodeRpcResponseList<YourType>> deserializer = new JsonDeserializer<NodeRpcResponseList<YourType>>() { @Override public NodeRpcResponseList<YourType> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { // ... } }; // 或者定义子类 public class ConcreteDeserializer extends CustomDeserializer<YourType> { // ... }
如果直接实例化CustomDeserializer本身(没有明确泛型参数),反射会拿到WildcardType,无法转为Class对象,所以方案1通常是更可靠、更易维护的选择。
内容的提问来源于stack exchange,提问作者C D
相关产品推荐
相关产品推荐

