我有一个像这样的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不会抱怨。这不是错的吗?我还在写一个实例方法的静态字段,只是通过静态方法,我不是吗?
答案 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
上讨论此决定背后的理由