gpt4 book ai didi

java - 如何在类型之间传递类型参数?

转载 作者:行者123 更新时间:2023-11-30 08:00:50 25 4
gpt4 key购买 nike

在将 retrofitGson 一起使用时,我遇到了一种情况,即提供的类型和最终类型不同但需要相同的类型参数。

我们在服务中有这个方法:

@GET("awesome")
AwesomeCall<AwesomeObject> get();

我希望 AwesomeCall 返回一个 AwesomeResult,其中包含相关的 AwesomeObject 或一个错误(请记住,这个“很棒的”API忽略 HTTP 并始终返回 200,只是给出一个错误对象而不是我们预期的 AwesomeObject)

我想要的是改造以解析 AwesomeResult 并使 AwesomeCall 在请求没有问题的情况下返回此类对象。

我遇到的问题是改造只为我提供了服务的返回类型,但我需要得到一个不同的对象。

PS:这样做是为了让服务没有任何对改造对象的引用,这些对象会泄漏到代码中的更高级别。

最佳答案

因此,在深入研究反射的深渊之后,我发现您可以实现 ParameterizedType(因为它是一个接口(interface))并使用它来生成与改造不同的调用。

在我的 CallAdapter.Factory 实现中,我创建了这个类型:

private static class AwesomeResponseType implements ParameterizedType {
private final Type innerType;

public BrainResponseType(Type innerType) {
this.innerType = innerType;
}

@Override
public Type[] getActualTypeArguments() {
return new Type[] {innerType};
}

@Override
public Type getRawType() {
return AwesomeResponse.class;
}

@Override
public Type getOwnerType() {
return null;
}
}

在创建适配器时,我像这样注入(inject)内部类型:

final Type innerType = getParameterUpperBound(0, (ParameterizedType) returnType);
ParameterizedType parameterizedType = new AwesomeResponseType(innerType);

并使用 parameterizedType 创建自定义 CallAdapter,如下所示:

private static class AwesomeCallAdapter<T> implements CallAdapter<AwesomeCall<?>> {

private final Type responseType;

private AwesomeCallAdapter(Type responseType) {
this.responseType = responseType;
}

@Override
public Type responseType() {
return responseType;
}

@SuppressWarnings("unchecked")
@Override
public <R> AwesomeCall<T> adapt(Call<R> call) {
return new AwesomeCall<>((Call<AwesomeResponse<T>>)call);
}

}

AwesomeCall 现在可以愉快地处理需要 AwesomeResponse 的调用:

public class AwesomeCall<T> {
private final Call<AwesomeResponse<T>> call;

public AwesomeCall(Call<AwesomeResponse<T>> call) {
this.call = call;
}

public AwesomeResponse<T> execute() throws IOException {
Response<BrainResponse<T>> response = call.execute();
return response.isSuccessful() ? response.body() : errorResponseFrom(response);
}

private AwesomeResponse<T> errorResponseFrom(Response<AwesomeResponse<T>> response) {
return new AwesomeResponse<>(null, new AwesomeError(response.message()));
}

}

如果您使用的是 Guava,我相信您不必实现 ParameterizedTypeTypeToken 有一个 API 可以执行此操作:

TypeToken.of(AwesomeResponse.class).where(new TypeParameter<T>() {}, innerType).getType();

但遗憾的是,Gson 中的 TypeToken 不支持该功能:(

关于java - 如何在类型之间传递类型参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38200551/

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