写入静态字段 - 在这种情况下FindBugs是错误的吗?

hto*_*que 9 java static-methods findbugs static-members

我有一个像这样的Java类:

public class Foo {

    public static int counter = 0;

    public void bar(int counter) {
        Foo.counter = counter;
    }
}
Run Code Online (Sandbox Code Playgroud)

FindBugs警告我counter通过实例方法写入静态字段bar.但是,如果我将代码更改为:

public class Foo {

    public static int counter = 0;

    public static void setCounter(int counter) {
        Foo.counter = counter;
    }

    public void bar(int counter) {
        setCounter(counter);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后FindBugs不会抱怨.这不是错的吗?我仍然通过静态方法从实例方法写入静态字段,不是吗?

dby*_*rne 15

假设在将来的某个时刻,您认为这个setter方法需要是线程安全的,并且您想要实现它synchronized.

这段代码可以正常工作:

public synchronized static void setCounter(int counter) {
    Foo.counter = counter;
}

public void bar(int counter) {
    setCounter(counter);
}
Run Code Online (Sandbox Code Playgroud)

此代码错误,行为不正确:

public synchronized void bar(int counter) {
    Foo.counter = counter;
}
Run Code Online (Sandbox Code Playgroud)

在这个人为的例子中,这似乎不是一个显着的差异,特别是因为counter通常只能标记volatile.然而,在一个现实世界的例子中,setter方法具有更复杂的逻辑,并且从许多不同的地方调用(不仅仅是从一个实例方法),后一种模式将更容易重构.

顺便说一下,在我看来,Google的CodePro Analytix插件是一个比FindBugs更快,更全面的工具.

有关:


bar*_*owc 5

错误描述的 FindBugs 列表中:

ST:从实例方法写入静态字段 (ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD)

此实例方法写入静态字段。如果操作多个实例,这很难纠正,而且通常是不好的做法。

通过从实例方法调用的静态方法访问静态字段没有类似的错误描述。

您可能想在 FindBugs邮件列表上讨论此决定背后的基本原理