【问题标题】:Incompatible types inferred type does not conform to equality constraint(s)不兼容的类型推断的类型不符合等式约束
【发布时间】:2017-11-03 01:46:05
【问题描述】:

所以我有一个模型Model

public class Model { .... } 

这有两个子类:

public class SubmodelA extend Model { .... }

public class SubmodelB extend Model { .... }

这三个封装在Data 类下。

public class ApiData<T extends Model> {

    public T data;

}

我的将军response wrapper 长这样:

public class ApiResponse<DATA> {

    DATA data;
}

“虚拟”api操作保持不变:

public interface Endpoints {

    Call<ApiResponse<ApiData>> getData();
}

我有一个retrofit2.Callback 的实现来处理响应:

public class ApiCallbackProxy<T> implements retrofit2.Callback<T> {

    public interface ApiResultListener<RESPONSE_TYPE> {
        void onResult(RESPONSE_TYPE response, ApiError error);
    }

    private ApiResultListener<T> mListener;

    private ApiCallbackProxy(ApiResultListener<T> listener) {
        mListener = listener;
    }

    @Override
    public void onResponse(Call<T> call, Response<T> response) {

    }

    @Override
    public void onFailure(Call<T> call, Throwable t) {

    }

    public static <T> ApiCallbackProxy<T> with(ApiResultListener<T> callback) {
        return new ApiCallbackProxy<>(callback);
    }
}

ApiClient

public class ApiClient {

    public Endpoints mRetrofit;

    public ApiClient() {
       Retrofit retrofit = new Retrofit.Builder().build();
       mRetrofit = retrofit.create(Endpoints.class);
    }

    public <U extends Model> void getData(ApiResultListener<ApiResponse<ApiData<U>>> callback) {
       //Compiler hits here
       mRetrofit.getData().enqueue(ApiCallbackProxy.with(callback));
    }
}

编译器在ApiCallbackProxy.with(callback) 出现此错误:

所以我想根据应用程序中使用此 API 调用的位置返回模型的不同子类或模型本身。

即。

public static void main (String[] args) {
    ApiClient apiClient = new ApiClient();
    apiClient.getData(listener2);
}


public static final ApiResultListener<ApiResponse<Data<SubmodelA>>> listener = (response, error) -> {};

public static final ApiResultListener<ApiResponse<Data<Model>>> listener2 = (response, error) -> {};

public static final ApiResultListener<ApiResponse<Data<SubmodelB>>> listener3 = (response, error) -> {};

【问题讨论】:

  • 什么是ChallengeData
  • 我的意思是 Payload :) 我将实际名称更改为更通用的名称。
  • 我明白了,我认为您还有一些类似的错误。如果您可以发布minimal reproducible example,那就太好了
  • @Manos 你可以添加字段mRetrofitApiInterface 的声明代码以及至少包含其签名的封闭类的摘录(名称、类型参数、超类/接口列表...)和关键领域/方法。谢谢。
  • 如果您提供minimal reproducible example,回答这个问题会容易得多。我们可以在没有其他依赖项的情况下进行编译,然后查看错误。

标签: java generics retrofit retrofit2


【解决方案1】:

ApiClient 类有一个侦听器,它在响应中期望ApiData&lt;U&gt;

问题是,没有U。您有一个Endpoint,端点没有泛型类型,它只返回ApiData,没有为泛型选择具体类型。

这是一个泛型出错的例子。通常的想法是使 Endpoint 通用:

public interface Endpoints<U> {
    Call<ApiResponse<ApiData<U>>> getData();
}

但是,Retrofit 是做什么的?它将 HTTP API 转换为 Java 接口。看看the most simple example at the github repo of Retrofit,我似乎很清楚你应该放置访问一些真正的HTTP端点的接口。不是什么抽象的GET

所以你宁愿给它一个具体的类型而不是让它通用。执行以下操作:

public interface Endpoints {
    Call<ApiResponse<ApiData<Model>>> getData();
}

我希望 Retrofit 能够反序列化响应您的 Model 的数据。因此,拥有一个具体的类而不是一个未设置的泛型类型变量对于成功的反序列化至关重要。但是,您只能将其与以下任一侦听器一起使用:

ApiResultListener<ApiResponse<Data<Model>>>
ApiResultListener<ApiResponse<Data<? super Model>>>

此外,在问题的较早部分,ApiResponse&lt;Payload&gt; 部分的泛型类型变量看起来像是 Payload 类,现在这很狡猾:)

【讨论】:

  • 将 Retrofit 服务接口设为通用接口是否明智?我将如何实例化它? mRetrofit = retrofit.create(Endpoints.class);
  • @Manos 我在阅读了关于 Retrofit 的最基本示例后编辑了答案。你做错的是,你的 Endpoints 是一些抽象类(我仍然发现复数粗略,但是 w/e),它在一些未指定的 HTTP 地址上执行 GET /data,返回未指定的数据类型。这部分是出错的地方——你需要给它一些与你调用的 REST 端点相对应的具体类型。我在答案中称它为MyDummyClass
  • 就问题而言,改造不会影响任何事情。我只是碰巧在使用它时遇到了错误。这就是为什么我没有提供@GET@POST 注释,因为它根本不相关。此外,引入一个新类对我来说似乎是多余的,因为假设的 HTTP 请求返回一个ApiData&lt;Model&gt;。我真的不明白为什么像Call&lt;ApiResponse&lt;ApiData&lt;Model&gt;&gt;&gt; getData();Call&lt;ApiResponse&lt;ApiData&lt;? extends Model&gt;&gt;&gt; getData(); 这样的东西不起作用。显然,我没有对泛型如何工作的强烈整合。一个解释会很好。
  • 嗯好的。看起来一些不相关的部分可能会导致麻烦。如果我看到实际代码,我很确定我会找出问题所在,这只是抽象层,导致我们浪费时间在你的赏金上。
  • 我使用的所有代码都在答案的EDITED 部分。时间就是金钱朋友,所以请不要把你的时间浪费在我的赏金上!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-04
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 2012-08-21
相关资源
最近更新 更多