Eclipse 中的@NonNullByDefault 和@Nullable 求值

@NonNullByDefault and @Nullable Evaluation in Eclipse

我正在使用 eclipse 空注释来检查我的代码中可能存在的 NPE。

我项目中的每个 class 都有 @NonNullByDefault 注释。 有些字段具有 @Nullable 注释。

这里是有问题的代码:

@NonNullByDefault
public class MyClass{
    @Nullable
    private File myFile;

    public MyClass() {
        ...
        // Somewhere here myFile may or may not be initialised
        ...
        myMethod();
    }

    public void myMethod() {
        ...
        if( myFile != null ) {
            //AnotherClass also has @NonNullByDefault on it
            AnotherClass.callStaticFunction( myFile );
        }
    }
}

这段代码现在给我错误信息:

Null type mismatch (type annotations): required '@NonNull File' but this expression has type '@Nullable File'

并且不会编译。

当我将方法更改为:

public void myMethod() {
    ...
    File another = myFile;
    if( another != null ) {
        AnotherClass.callStaticFunction( another );
    }
}

代码将在没有任何抱怨的情况下编译。

为什么会这样?

online documentation 包含一个段落 "The case of fields",其中详细说明了访问字段所涉及的复杂性。本质上,流分析只能对当前作用域拥有的变量做出准确的陈述。局部变量 由声明它们的块拥有,字段 由任何词法范围拥有,因此容易产生意想不到的效果,因为任何

  • effects via aliased references
  • side effects of another method
  • concurrency

相同的帮助文本还概述了两种可能的解决方案(除了引入更多注释,例如指定所有权):

  • 处理前分配给局部变量
  • "syntactic analysis",识别一组有限的模式,这些模式在正常情况下足够安全(在这种情况下没有给出完全保证)。

这些策略中的第一个通常应该是首选,这也是问题中提到的 - 所以你应该没问题。

最后,我要提到的是存在一个 RFE 来引入像 @LazyNonNull 这样的注释,它基本上表示以下内容:

  • 没有必要在所有构造函数中初始化这些字段。
    • 因此,该字段可能是 null
  • 不可能分配 null给这样的字段。
    • 因此,对该字段进行空检查足以在检查后假设为非空。

更多表达此方向需求的评论可能有助于激励对此类解决方案的投资。