gpt4 book ai didi

java - 使用 Java 泛型反序列化

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:08:38 25 4
gpt4 key购买 nike

考虑这个外部执行类

public class ExternalCommands {

private Logger log = LoggerFactory.getLogger(ExternalCommands.class);

private static final ObjectMapper objectMapper = new ObjectMapper();

public <T> CustomResponse<T> executeQuery(Clients client, Query query, Class<T> classType) throws Exception {
if (Objects.isNull(clients))
throw new Exception("external client is null in external commands");

log.debug("Query : {}", query);
Response queryResponse = clients.getElasticClient().executeQuery(query);
log.debug("query response : {}", queryResponse);
if (queryResponse.status() == 200) {
JavaType javaType = objectMapper.getTypeFactory().constructParametricType(CustomResponse.class, classType); // This is the coding sin m talking about
return objectMapper.readValue(queryResponse.body().asInputStream(), javaType);
}
}
}

所以基本上这个 executeQuery 函数根据 query 从弹性客户端获取所有数据,并根据发送的通用 classType 反序列化它在函数中
但是
这更像是显式进行反序列化,而不是使用泛型


请参阅下面的代码,了解此执行如何与内联注释一起工作:

public ArrayList<EmpData> getEmpData() throws Exception {
ArrayList<EmpData> merchantUrnMap = new ArrayList<>();

List<Filter> filters = new ArrayList<>();
filters.add("Added filter 1 here");
filters.add("Added filter 2 here");
filters.add("Added filter 3 here");

ExternalCommands commands = new ExternalCommands();
Query query = commands.getQuery(filters);
// get "clients"

// this is how it works now
CustomResponse<EmpData> response = commands.executeQuery(clients, query, EmpData.class);

// this is how i WANT IT TO WORK - without passing "EmpData.class"
// but in this case <T> in "CustomResponse<T>" would not deserialise to "EmpData"
// resulting in LinkedHashMap in deseralised object instead of class object
// CustomResponse<EmpData> response = commands.<EmpData>executeQuery(clients, query);


// some operations
return response

}

关于如何实现这一点有什么建议吗?

最佳答案

案例 1:假设 constructParametricType需要 classType参数才能正常运行,并且您不能更改隐含但未在您发布的代码中提供的方法/类的实现。

由于 type erasure,您建议的方法签名/调用不可能在 Java 中。

您使用 classTypeconstructParametricType(CustomResponse.class, classType)打电话,你正在尝试替换 classTypeT不知何故。这是不可能的,因为编译代码时,T被完全删除。没有办法做类似 constructParametricType(CustomResponse.class, T.class) 的事情因为T在运行时不存在。

正确的解决方案是将类作为方法参数传入,这正是您现有方法所做的。


情况 2:您真的想要调用电话 commands.<EmpData>executeQuery(clients, query);并且您愿意为实现该目标做出任何改变。

因为我们不能通过T作为 constructParametricType 的参数, 它必须被称为 constructParametricType(CustomResponse.class) , 但它需要返回 JavaType代表CustomResponse<T> .唯一的方法就是声明

<T> JavaType<T> constructParametricType(Class<?> cls)

请注意 JavaType出于同样的原因,现在也必须进行参数化(我们无法在运行时获得 T)。最后,我们要声明

CustomResponse<T> readValue(InputStream stream, JavaType<T> javaType)

匹配 executeQuery 声明的返回类型.

在所有这些更改之后,该行

CustomResponse<EmpData> response = commands.<EmpData>executeQuery(clients, query);

应该编译。这是一个最小的例子:

class CustomResponse<T> {}
class Clients{}
class Query{}
class EmpData{}

class ObjectMapper {
JavaTypeFactory getTypeFactory() {
return new JavaTypeFactory();
}
<T> CustomResponse<T> readValue(InputStream s, JavaType<T> j) {
return new CustomResponse<>();
}
}

class JavaTypeFactory {
<T> JavaType<T> constructParametricType(Class<?> cls) {
return new JavaType<>(cls);
}
}

class JavaType<T> {
JavaType(Class<?> cls) {}
}

class ExternalCommands {
private static final ObjectMapper objectMapper = new ObjectMapper();

public <T> CustomResponse<T> executeQuery(Clients clients, Query query) throws Exception {
InputStream queryResponseStream = null;
JavaType<T> javaType = objectMapper.getTypeFactory().<T>constructParametricType(CustomResponse.class);
return objectMapper.readValue(queryResponseStream, javaType);
}
}

class SomeClass {
public void getEmpData() throws Exception {
ExternalCommands commands = new ExternalCommands();
Query query = null;
Clients clients = null;
CustomResponse<EmpData> response = commands.<EmpData>executeQuery(clients, query);
}
}

请注意,鉴于您系统的其余部分(尤其是参数化 JavaType ),某些描述的更改可能并不容易/不可能,我不推荐这种方法。我建议坚持你所拥有的;这是 IMO 最干净的方法。

关于java - 使用 Java 泛型反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49939122/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com