I'm using the external null annotation facility available in Eclipse Mars. I'm trying to add an external annotation for java.lang.Object#getClass()
but can't seem to get the signature right. I've tried the following variations:
@NonNull Class<?> getClass() [()L1java/lang/Class<*>;]
@NonNull Class<@NonNull ?> getClass() [()L1java/lang/Class<*1>;]
but continue to get a warning when passing the result of invoking getClass()
to a method that accepts an instance of Class<?>
, where that parameter is annotated with @NonNull
.
Below are the relevant files from a minimal Eclipse Mars project that reproduces the issue (this example uses the first null annotation variation above, but I also get the same warning when using the second variation):
Eclipse Mars Release (4.5.0; 20150621-1200) for Windows 64-bit
Oracle JDK 1.8.0_60
src/bar/Foo.java
package bar;
public class Foo {
private static void printType(Class<?> type) {
System.out.println(type.getName());
}
public static void main(String[] args) {
Foo foo = new Foo();
printType(foo.getClass());
}
}
src/bar/package-info.java
@org.eclipse.jdt.annotation.NonNullByDefault
package bar;
annotations/java/lang/Object.eea
class java/lang/Object
getClass
()Ljava/lang/Class<*>;
()L1java/lang/Class<*>;
.settings/org.eclipse.jdt.core.prefs (partial)
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=enabled
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=warning
org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
...
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
...
org.eclipse.jdt.core.compiler.compliance=1.8
...
org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
...
org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
org.eclipse.jdt.core.compiler.problem.nullReference=error
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
...
org.eclipse.jdt.core.compiler.problem.potentialNullReference=error
...
org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
...
org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=enabled
...
org.eclipse.jdt.core.compiler.source=1.8
.classpath
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="annotationpath" value="/null-annotation-test/annotations"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="org.eclipse.jdt.annotation_2.0.100.v20150311-1658.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
For the above project, I receive the following warning on line 10 of Foo.java (where printType
is called):
Null type safety (type annotations): The expression of type 'Class<capture#of ? extends Foo>' needs unchecked conversion to conform to '@NonNull Class<?>'
which is the same warning I get without the external null annotation being present.
How do I correctly create an external null annotation for java.lang.Object#getClass()
to remove this warning? Or is my problem in the declaration of printType
?
Louis Wasserman is correct, in terms of type checking there is not one
getClass()
method, but each class has it's own method with specialized signature. Hence no signature in a .eea file will ever match the actual getClass() methods.I filed an RFE to put more special knowledge about
getClass()
into the compiler, so that no external annotations are needed for this beast.EDIT: This feature has been implemented and will be released with Eclipse 4.6 (Neon).