无法使用父级变量类型并接收子级类型

5

你好,我正在使用 Java 8 进行工作。以下是具体情况:

我有一个空接口 AsyncResponse,如下所示:

package com.personal.carrot.core.models;

public interface AsyncResponse {
}

我有一个名为APIResponse的模型。

package com.personal.carrot.core.models;

import org.codehaus.jackson.annotate.JsonProperty;

public class APIResponse implements AsyncResponse {

    @JsonProperty("numberOfFeatures")
    public Long numberOfFeatures;

}

最后,我使用Retrofit2创建了一个用于处理API响应的服务:

public interface APIRepository {
    @POST("MYURL")
    Call<APIResponse> resolveCounts(@Body HashMap<String, String> body);
}

现在,当我像下面这样调用APIRepository时:
Call<AsyncResponse> request = repository.resolveCounts(payload);

我遇到了一个错误:

Java:不兼容的类型:retrofit2.Call(com.personal.carrot.core.models.APIResponse)无法转换为retrofit2.Call(com.personal.carrot.core.models.AsyncResponse)

这个错误是因为无法将APIResponse对象转化成AsyncResponse对象。

1
@ernest_k 不,这是单个实例的JVM,并且这是编译时错误。 - iam.Carrot
如果使用 Call<? extends AsyncResponse>,它能正常工作吗? - Hulk
参见Oracle泛型教程:“Box<Integer>和Box<Double>不是Box<Number>的子类型” - 如果resolveCounts返回一个Call<APIResponse>,则不能将其分配给Call<AsyncResponse> - Hulk
参见:https://dev59.com/VnE95IYBdhLWcg3wApHk - Hulk
2个回答

1

它失败是因为你不能将Call<APIResponse>分配给Call<AsyncResponse>。泛型类型是不变的。

你可能需要将APIResponse用作变量的类型参数:

Call<APIResponse> request = repository.resolveCounts(payload);

这并不是因为你无法设计你的代码以使用接口AsyncResponse,而是因为(我在这里假设)框架使用返回类型来处理与内容类型相关的绑定。

0

为什么它不起作用

与普遍理解的多态性相反(这是您在此处尝试实现的内容),它不适用于泛型。

List<String> strList = new ArrayList();
List<Object> objectList = strList;

上述示例将产生编译错误。

这是因为如果我们允许第二行成功,可能会出现一种情况,随后objectList被分配了另一种类型的列表(例如List<Integer>)。 strList现在将被“破坏”,因为objectList持有与strList相同的引用。

因此,我们需要返回与该列表明确声明要保存的类型完全相同的类型,而不是AsyncResponse的子类或超类。

潜在解决方案

根据您在此处尝试实现的内容,一个潜在的解决方案可能是:

Call<APIResponse> request = repository.resolveCounts(payload);

或者(我还没有尝试过这个):

Call<? extends ASyncResponse> request = repository.resolveCounts(payload);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接