具有泛型的java类层次结构中的不兼容的nullness约束

时间:2016-01-15 17:26:29

标签: java eclipse generics eclipse-jdt type-annotation

我正在将我的java代码库从java7迁移到java8。在这个过程中,我也从javax.annotation @Nullable,@ NonNull和@ParametersAreNotNullByDefault注释切换到eclipse中的null分析的org.eclipse.jdt注释(Mars Release 4.5.0:Build id:20150621-1200)。 在这样做的过程中,我偶然发现了一个我无法编译的情况(因为关于基于注释的空检查的严格eclipse设置),因为我无法解释。我不是想找到一种编译代码的方法,而是更多地了解错误发生的原因。

我在一个包中使用@NonNullByDefault中的package-info.java指定默认非空值。

我有一个抽象类实现的接口,而抽象类又由具体类扩展,如下所示:

public interface SimulationComponent {

    <T extends SimulationComponent> List<T> getCorrectSimulationSubComponents();

    List<? extends SimulationComponent> getErroneousSimulationSubComponents();
}


public abstract class AbstractSimulationComponent
        implements SimulationComponent {

    @Override
    public List<SimulationComponent> getCorrectSimulationSubComponents() {
        return Collections.emptyList();
    }

    @Override
    public List<SimulationComponent> getErroneousSimulationSubComponents() {
        return Collections.emptyList();
    }
}

public class ConcreteSubSimComponent extends AbstractSimulationComponent {
    public void doSomething() {
    }
}

Eclipse在ConcreteSubSimComponent中通知我以下问题:

The method @NonNull List<@NonNull SimulationComponent> getErroneousSimulationSubComponents() from 
 AbstractSimulationComponent cannot implement the corresponding method from SimulationComponent due 
 to incompatible nullness constraints

此问题似乎是由getErroneousSimulationSubComponents()中的泛型通配符引起的。这就是我在迁移到java8时指定导致我注意到问题的方法的方法。 我发现我可以很容易地&#39;只需将此方法签名替换为getCorrectSimulationSubComponents()中显示的签名即可解决问题。 我不明白为什么最后一个版本有效,而之前的版本没有。

此外,这似乎只是具体子类中的问题。直接实现接口的具体类没有显示任何问题。

我正在使用JavaSE-1.8和一个带有无法编译代码的示例项目,可以在https://github.com/KrisC369/NullProblemIllustration找到

1 个答案:

答案 0 :(得分:1)

显然,这个bug已经通过修复针对JDT-core的bug 436091所引入的更改得到了解决。 这个修复应该出现在eclipse Mars.2(4.5.2)和eclipse neon-M4(4.6.0-M4)中。