Eclipse中的@NonNullByDefault和@Nullable评估

时间:2018-08-27 14:15:54

标签: java annotations nullable

我正在使用eclipse空注解来检查代码中是否存在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 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 );
    }
}

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

为什么会这样?

1 个答案:

答案 0 :(得分:2)

online documentation包含“字段的情况”段落,其中详细说明了访问字段所涉及的复杂性。本质上,流分析只能对当前范围拥有的变量做出准确的陈述。局部变量 由声明它们的块拥有,字段不由任何词法作用域拥有,因此由于任何

  
      
  • 通过别名引用产生的效果
  •   
  • 另一种方法的副作用
  •   
  • 并发
  •   

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

  • 在处理之前分配给局部变量
  • “句法分析”,它识别出在正常情况下足够安全的有限模式(在这种情况下,没有给出充分的保证)。

通常应该首选这些策略中的第一种,这也是问题中提到的-因此您应该没事。

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

  • 没有必要在所有构造函数中初始化此类字段。
    • 因此,该字段可能是null
  • 无法分配 null到这样的字段。
    • 因此,对该字段执行空检查就足以在检查之后假设为非空。

更多表示在此方向上的需求的评论可能有助于激励投资以寻求这种解决方案。