java class 层次结构中不兼容的 nullness 约束与泛型
Incompatible nullness constraints in java class hierarchy with generics
我正在将项目的 java 代码库从 java7 迁移到 java8。在此过程中,我还从 javax.annotation @Nullable、@NonNull 和 @ParametersAreNotNullByDefault 注释切换到 org.eclipse.jdt 注释,以便在 eclipse 中进行空分析(Mars Release 4.5.0:Build id: 20150621-1200 ).
在这样做的过程中,我偶然发现了我无法编译的情况(因为关于基于注释的空检查的严格 eclipse 设置),因为一些我无法解释的事情。我不是想找到一种方法来编译我的代码,而是想了解为什么会发生错误。
我在包中有以下 classes,在 package-info.java
.
中使用 @NonNullByDefault
指定默认非空性
我有一个由抽象 class 实现的接口,它又由具体 class 扩展如下:
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 时注意到问题的方法的方式。
我发现我可以 'easily' 通过将此方法签名替换为 getCorrectSimulationSubComponents()
中显示的方法签名来解决问题。
我不明白为什么最后一个版本有效而以前的版本无效。
此外,这似乎只是具体子class中的问题。直接实现接口的具体 class 没有显示任何问题。
我正在使用 JavaSE-1.8 和一个代码无法编译的示例项目,可以在 https://github.com/KrisC369/NullProblemIllustration
找到
显然,此错误已通过针对 JDT-core 修复错误 436091 而引入的更改解决。
此修复程序应存在于 eclipse Mars.2 (4.5.2) 和 eclipse neon-M4 (4.6.0-M4) 中。
我正在将项目的 java 代码库从 java7 迁移到 java8。在此过程中,我还从 javax.annotation @Nullable、@NonNull 和 @ParametersAreNotNullByDefault 注释切换到 org.eclipse.jdt 注释,以便在 eclipse 中进行空分析(Mars Release 4.5.0:Build id: 20150621-1200 ). 在这样做的过程中,我偶然发现了我无法编译的情况(因为关于基于注释的空检查的严格 eclipse 设置),因为一些我无法解释的事情。我不是想找到一种方法来编译我的代码,而是想了解为什么会发生错误。
我在包中有以下 classes,在 package-info.java
.
@NonNullByDefault
指定默认非空性
我有一个由抽象 class 实现的接口,它又由具体 class 扩展如下:
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 时注意到问题的方法的方式。
我发现我可以 'easily' 通过将此方法签名替换为 getCorrectSimulationSubComponents()
中显示的方法签名来解决问题。
我不明白为什么最后一个版本有效而以前的版本无效。
此外,这似乎只是具体子class中的问题。直接实现接口的具体 class 没有显示任何问题。
我正在使用 JavaSE-1.8 和一个代码无法编译的示例项目,可以在 https://github.com/KrisC369/NullProblemIllustration
找到显然,此错误已通过针对 JDT-core 修复错误 436091 而引入的更改解决。 此修复程序应存在于 eclipse Mars.2 (4.5.2) 和 eclipse neon-M4 (4.6.0-M4) 中。