I am in the middle of migrating my java codebase for a project from java7 to java8. In the process I am also switching from the javax.annotation @Nullable, @NonNull and @ParametersAreNotNullByDefault annotations to the org.eclipse.jdt annotations for null-analysis in eclipse (Mars Release 4.5.0:Build id: 20150621-1200). In doing this, I stumbled upon a situation where I can't compile (because of strict eclipse settings with regard to annotation based null checking) because of something I can't explain. I am not looking to find a way to compile my code, but more to understand why the error is occurring.
I have the following classes in a package specifying default non nullness using @NonNullByDefault
in a package-info.java
.
I have an interface implemented by an abstract class which is in turn extended by a concrete class as follows:
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 notifies me of the following problem in ConcreteSubSimComponent:
The method @NonNull List<@NonNull SimulationComponent> getErroneousSimulationSubComponents() from
AbstractSimulationComponent cannot implement the corresponding method from SimulationComponent due
to incompatible nullness constraints
This problem seems to be caused by the generics wildcard in getErroneousSimulationSubComponents()
. This is how I specified the method that resulted in me noticing the problem when migrating to java8.
I figured out that I could 'easily' fix things by just replacing this method signature to the one shown in getCorrectSimulationSubComponents()
.
I don't see why this last version works and the previous version doesn't.
Also, this only seems to be a problem in the concrete subclass. A concrete class directly implementing the interface does not show any problems.
I am using JavaSE-1.8 and an example project with the code that does not compile, can be found at https://github.com/KrisC369/NullProblemIllustration
Apparantly, this bug has been resolved by the changes introduced to fix bug 436091 against JDT-core. This fix should be present in eclipse Mars.2 (4.5.2) and eclipse neon-M4 (4.6.0-M4).