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

时间:2012-11-14 22:57:35

标签: java static-methods static-members findbugs

我有一个像这样的Java类:

public class Foo {

    public static int counter = 0;

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

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);
    }
}

然后FindBugs不会抱怨。这不是错的吗?我还在写一个实例方法的静态字段,只是通过静态方法,我不是吗?

2 个答案:

答案 0 :(得分:14)

假设在将来的某个时刻,您认为此setter方法需要是线程安全的,并且您希望将其设为synchronized

此代码可以正常工作:

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

public void bar(int counter) {
    setCounter(counter);
}

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

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

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

另外,在我看来,Google's CodePro Analytix插件是比FindBugs更快,更全面的工具。

相关:

答案 1 :(得分:4)

来自bug descriptions的FindBugs列表:

  

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

     

此实例方法写入静态字段。得到这个很棘手   如果正在操作多个实例,则更正,并且通常是错误的   实践。

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

您可能希望在FindBugs mailing list

上讨论此决定背后的理由