Java @Eclipse中的NonNullByDefault和@Nullable求值

Java @Eclipse中的NonNullByDefault和@Nullable求值,java,annotations,nullable,Java,Annotations,Nullable,我正在使用EclipseNull注释检查代码中可能存在的NPE 我的项目中的每个类都有@NonNullByDefault注释。 有些字段具有@Nullable注释 下面是有问题的代码: @NonNullByDefault public class MyClass{ @Nullable private File myFile; public MyClass() { ... // Somewhere here myFile may or ma

我正在使用EclipseNull注释检查代码中可能存在的NPE

我的项目中的每个类都有
@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类型不匹配(类型批注):需要'@NonNull File',但此表达式的类型为'@Nullable File'

不会编译

当我将方法更改为:

public void myMethod() {
    ...
    File another = myFile;
    if( another != null ) {
        AnotherClass.callStaticFunction( another );
    }
}
该代码将在没有任何投诉的情况下编译

为什么会这样?

包含一段“字段的情况”,详细说明了访问字段所涉及的复杂性。本质上,流分析只能对当前范围所拥有的变量做出准确的陈述。局部变量归声明它们的块所有,字段不归任何词法作用域所有,因此容易由于以下任何原因而产生意外效果:

  • 通过别名引用的效果
  • 另一种方法的副作用
  • 并发性
同一帮助文本还概述了两种可能的解决方案(除了引入更多注释,例如指定所有权):

  • 处理前对局部变量赋值
  • “句法分析”,它识别一组有限的模式,这些模式在正常情况下是足够安全的(在这种情况下没有给出充分的保证)
这些策略中的第一个通常是首选的,这也是问题中提到的——所以你应该很好

最后,我要提到的是,存在一个类似于
@lazynoll
的注释,它基本上会发出以下信号:

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

更多的评论表达了这方面的需求,这可能有助于推动对此类解决方案的投资。

这只是一种猜测,因为测试后myFile可能会从另一个线程修改?