【问题标题】:"Incompatible Types" error in IDE, but code compilesIDE 中出现“不兼容的类型”错误,但代码可以编译
【发布时间】:2013-09-14 10:18:57
【问题描述】:

我有一系列相关的课程。还有一些继承的东西似乎让我的 IDE 无法使用。但是我的代码编译得很好。

在我的响应子类中,我试图将错误字段限制为仅包含错误子类。理想情况下,我希望公共 getter 返回List<GWSError>,这样我就不必继续在使用该方法的其他类中强制转换它。我试图重写继承的 getter 和 setter 来执行此操作,但我的 IDE 一直给我一个不兼容的类型错误。 NetBeans 和 Eclipse 在相同的方法上都会出错。

我在下面包含了我的代码示例以澄清这一点。为清楚起见,省略了与此问题无关的代码。

正如我所提到的,当我直接使用 Maven 编译它时,我没有遇到任何编译器错误。

这让我觉得必须有更好的方法来实现这一点。但我不知道那是什么。


基本响应类

public class WSResponse {

    protected List<WSError> errors;

    public List<WSError> getErrors(){
        if(errors == null){
            setErrors(new ArrayList<WSError>());
        }

        return errors;
    }

    public void setErrors(List<WSError> errors) {
        this.errors = errors;
    }
}

响应子类

public class GResponse extends WSResponse{

    @Override //IDE Error: getErrors() in GResponse cannot override getErrors() in WSResponse; return type List<GWSError> is not compatible with List<WSError>
    public List<GWSError> getErrors(){
        if(errors == null){
            errors = new ArrayList<GWSError>();
        }

        return errors;
    }

    @Override  //IDE Error: name clash: setErrors(List<GWSError>) in GtmResponse and setErrors(List<WSError>) in WSResponse have the same erasure, yet neither overrides the other
    public void setErrors(List<GWSError> errors){
        this.errors = errors;
    }

    public void addError(GWSError error){
        getErrors().add(error);
    }
}

基本错误类

public class WSError {

}

错误子类

public class GWSError extends WSError{

}

【问题讨论】:

  • 老实说,听起来你遇到了一个基本的设计问题 - 我不能像使用其他任何 WSResponse 一样使用 GResponse。您正在缩小子类的使用方式,这违反了正常的继承。我很惊讶这在 Maven 中有效。
  • 我不能不同意,但我不确定如何解决这个问题。 GResponse 是 WSResponse 的一个特例,因此子类似乎是合适的。与 GError 相同。但是,GResponse 类依赖于 GError 子类中的额外信息。使 GError 成为自己的类的解决方案吗?但是它会从 WSError 类中复制代码。我可以接受这是一个设计问题,但我正在寻求一些关于如何解决它的反馈。
  • 您的问题实际上并没有要求对设计提供任何反馈 - 它只是关于为什么它在一个地方编译而不在另一个地方编译,这是非常不同的。

标签: java inheritance


【解决方案1】:

首先,您应该了解泛型是不变的。因此,您不能将返回类型从 List&lt;WSError&gt; 更改为 List&lt;GWSError&gt;

当我直接用 Maven 编译它时,我没有遇到任何编译器错误。

这让我很惊讶。您的代码目前无法在任何 Java 编译器级别下编译。

我想你真的应该让你的 WSResponse 类通用。这样,您可以轻松地创建并行继承层次结构,就像您在您的案例中尝试做的那样。因此,将您的类修改为:

class WSResponse<T extends WSError> {
    protected List<T> errors;

    public List<T> getErrors(){
        if(errors == null){
            setErrors(Collections.<T>emptyList());
        }

        return errors;
    }

    public void setErrors(List<T> errors) {
        this.errors = errors;
    }
}

然后扩展这个类的具体参数化类型:

class GResponse extends WSResponse<GWSError> {

    @Override
    public List<GWSError> getErrors() {
        return super.getErrors();
    }

    @Override
    public void setErrors(List<GWSError> errors) {
        super.setErrors(errors);
    }
}

【讨论】:

    【解决方案2】:

    这是因为泛型和类型擦除,方法是冲突的,因为它们基本上都是在编译之后 List

    List&lt;GWError&gt; 不继承自 List&lt;WSError&gt; 这不是它在 Java 中的工作方式。

    这在 SO 和 Google 上都有很好的记录。

    如果你只是谷歌实际的错误信息,你会发现很多非常详细的解释,这里有两个很长的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-18
      • 2010-11-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多