使用Java Checker Framework的Nullness Checker注释重入

时间:2014-10-15 08:21:43

标签: java nullable checker-framework

我正在使用Java 8尝试Checker Framework的Nullness检查程序。当我在以下代码上运行检查程序时:

import java.util.HashMap;
import java.util.Map;

import org.checkerframework.checker.nullness.qual.Nullable;

class A {
    public void f() {}
}

public class Foo {
    private Map<A,Integer> map = new HashMap<>();
    private @Nullable A x;

    public void setX(@Nullable A x) {
        this.x = x;
    }

    public void call() {
        if (x != null) {
            map.put(x, 0);
            x.f();
        }
    }
}

检查器在x.f();上发出警告:取消引用可能的空引用x。当然,这是有道理的。 Checker Framework不知道map.put做了什么。地图对象可能已引用this,然后在其上调用setX(null)

现在我的问题如下。有没有办法告诉Checker Framework一个方法不会修改除了它所调用的对象之外的任何对象?由于map.put没有调用setX方法,因此x的值不会改变。

要摆脱警告,我可以将调用方法更改为:

public void call() {
    A y = x;
    if (y != null) {
        map.put(y, 0);
        y.f();
    }
}

现在没有警告。这也是有道理的:无法从外部访问局部变量。但我不想引入这个局部变量,其唯一目的是消除警告。

或者,我可以通过x注释字段@MonotonicNonNull。但在我的实际用例中,我希望保持将字段设置为null的可能性。

提前致谢!

1 个答案:

答案 0 :(得分:1)

你的问题已经提供了几种抑制警告的好方法,所以你清楚地知道你在做什么。

但是,你想要一个更好的方法。您想知道如何使Checker Framework从不发出警告。你的关键问题是:

  

有没有办法告诉Checker Framework一个方法不会修改除被调用对象之外的任何对象?

不幸的是,Checker Framework目前没有此功能。 Manual section 21.4.3, "Side effects, determinism, purity, and flow-sensitive analysis", 讨论了Checker Framework如何表明纯度或无副作用。 @SideEffectFree和@Pure注释目前是全有或全无。

您对部分纯度注释的建议会很有用:它会使Checker Framework更具表现力,并且可以减少抑制警告的需要,这是目前所需要的。 (另一方面,用户学习也是另一回事;总是存在表达性 - 复杂性权衡。)我建议你向Checker Framework开发人员提出这个功能。