Внешняя нулевая аннотация Eclipse для java.lang.Object#getClass()

Я использую средство внешней нулевой аннотации, доступное в Eclipse Mars. Я пытаюсь добавить внешнюю аннотацию для java.lang.Object#getClass(), но не могу правильно подобрать подпись. Я пробовал следующие варианты:

@NonNull Class<?> getClass() [()L1java/lang/Class<*>;]
@NonNull Class<@NonNull ?> getClass() [()L1java/lang/Class<*1>;]

но продолжать получать предупреждение при передаче результата вызова getClass() методу, который принимает экземпляр Class<?>, где этот параметр помечен @NonNull.

Ниже приведены соответствующие файлы из минимального проекта Eclipse Mars, который воспроизводит проблему (в этом примере используется первый вариант нулевой аннотации выше, но я также получаю такое же предупреждение при использовании второго варианта):

Выпуск Eclipse Mars (4.5.0; 20150621-1200) для 64-разрядной версии Windows
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 (частично)

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>

Для приведенного выше проекта я получаю следующее предупреждение в строке 10 файла Foo.java (где вызывается printType):

Null type safety (type annotations): The expression of type 'Class<capture#of ? extends Foo>' needs unchecked conversion to conform to '@NonNull Class<?>'

это то же самое предупреждение, которое я получаю без внешней нулевой аннотации.

Как правильно создать внешнюю нулевую аннотацию для java.lang.Object#getClass(), чтобы удалить это предупреждение? Или моя проблема в объявлении printType?


person Rusty Shackleford    schedule 16.09.2015    source источник
comment
Я не уверен, что это возможно. getClass — глубоко магическая функция; это обрабатывается специально в проверке типов компилятора.   -  person Louis Wasserman    schedule 16.09.2015


Ответы (1)


Луи Вассерман прав, с точки зрения проверки типов не существует одного метода getClass(), но у каждого класса есть свой метод со специализированной сигнатурой. Следовательно, никакая подпись в файле .eea никогда не будет соответствовать фактическим методам getClass().

Я подал RFE, чтобы добавить в компилятор дополнительные сведения о getClass(), так что никакие внешние аннотации для этого зверя не нужны.

EDIT: эта функция реализована и будет выпущена в Eclipse 4.6 (Neon).

person Stephan Herrmann    schedule 17.09.2015