Eclipse null分析为类文字发出null类型安全警告

时间:2015-09-18 02:42:21

标签: java eclipse null annotations eclipse-jdt

考虑以下启用了空分析的Eclipse项目的部分内容:

用于Windows 64位的Eclipse Mars版本(4.5.0; 20150621-1200)
Oracle JDK 1.8.0_60

package-info.java

@org.eclipse.jdt.annotation.NonNullByDefault
package bar;

Foo.java

package bar;

public class Foo {
    public static void main(String[] args) {
    }
}

class Base<T> {
    private final Class<T> type;

    public Base(Class<T> type) {
        this.type = type;
    }

    public Class<T> getType() {
        return this.type;
    }
}

class Derived extends Base<String> {
    public Derived() {
        super(String.class); // <-- Null type safety warning here
    }
}

Null分析在Derived中对超类ctor的调用中产生以下警告:

Null type safety (type annotations): The expression of type 'Class<String>' needs unchecked conversion to conform to '@NonNull Class<@NonNull String>'

避免此警告的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

您所看到的冲突是在类型参数之间......

  • ...所需类型:@NonNull String
  • ...提供的类型:String

来自extends Base<String>的{​​{1}}图片中出现了非空类型参数,该版本在@NonNullByDefault制度下扩展为extends Base<@NonNull String>。从这里开始渗透到超级构造函数,在类型参数替换后将其签名呈现为(@NonNull Class<@NonNull String>)。相比之下,编译器将类文字看作具有类型@NonNull Class<String>,这是不兼容的。

真正的解决方案将来自Bug 477719,特别参见评论3 f中的讨论。

目前(使用Eclipse Mars)您可能必须减少@NonNullByDefault的影响,以便接受@NonNull Class<String>。这可以通过类{@ 1}}之类的更具体的@NNBD声明来实现,就像这样

Derived

在这里,我们正在利用这一事实,@ NNBD可以根据其适用的位置进行微调。在此声明中,与无参数import static org.eclipse.jdt.annotation.DefaultLocation.*; ... @NonNullByDefault({PARAMETER, RETURN_TYPE, FIELD, TYPE_BOUND}) class Derived extends Base<String> { ... 的区别在于省略了位置@NonNullByDefault,这意味着TYPE_ARGUMENT中的String将不再像上面提到的那样受到影响。因此,超级构造函数将具有此签名:extends Base<String>并且所有编译都没有警告。

通过将精细调整的@NNBD放在类(@NonNull Class<String>)上,此变通办法的范围尽可能小。