将retrofit与Gson一起使用时,遇到了一种情况,即提供的类型和最终类型不同,但需要相同的type参数。我们在服务中使用此方法:@GET("awesome")AwesomeCall<AwesomeObject> get();我想让AwesomeCall返回一个包含相关AwesomeResult或错误的AwesomeObject(请记住,这个“很棒的” API会忽略HTTP并始终返回200,只是提供一个错误对象而不是我们期望的)我想要的是进行改造,以解析AwesomeObject并在请求没有问题的情况下使AwesomeResult返回此类对象。我遇到的问题是,改型仅向我提供了服务的返回类型,但是我需要获取其他对象。PS:这样做是为了使服务没有对​​可能泄漏到代码较高级别中的改造对象的任何引用。 (adsbygoogle = window.adsbygoogle || []).push({}); 最佳答案 因此,在深入研究了反射的深渊之后,我发现您可以实现ParameterizedType(因为它是一个接口),并使用它生成与改造不同的调用。在我的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; }}在创建适配器时,我像这样注入内部类型: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,我相信您不必实现ParameterizedType。 TypeToken具有执行此操作的API:TypeToken.of(AwesomeResponse.class).where(new TypeParameter<T>() {}, innerType).getType();但是可悲的是,Gson中的TypeToken不支持该功能:( (adsbygoogle = window.adsbygoogle || []).push({});
10-07 18:46