Запись в статическое поле — ошибается ли 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 не будет жаловаться. Разве это не неправильно? Я все еще пишу в статическое поле из метода экземпляра, только через статический метод, не так ли?


person htorque    schedule 14.11.2012    source источник
comment
Дайте мне знать, когда автоматизированные инструменты смогут обнаруживать все виды программных ошибок, чтобы я мог начать поиски новой карьеры.   -  person NullUserException    schedule 15.11.2012
comment
Но в данном случае это только один вид. : P Я новичок в этом инструменте и еще не знаю, насколько надежны его результаты. :)   -  person htorque    schedule 15.11.2012
comment
Если FindBugs выдает предупреждение, вам лучше посмотреть на проблему. Но это не означает, что если FindBugs не выдает никаких предупреждений, ваш код идеален и не содержит ошибок.   -  person JB Nizet    schedule 15.11.2012


Ответы (2)


Предположим, что в какой-то момент в будущем вы решите, что этот метод установки должен быть потокобезопасным, и вы хотите сделать его 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. Однако в реальном примере, где метод установки имеет более сложную логику и вызывается из многих разных мест (а не только из одного метода экземпляра), последний шаблон будет легче рефакторить.

Кроме того, на мой взгляд, плагин Google CodePro Analytix намного более быстрый и комплексный инструмент, чем FindBugs.

Связанный:

person dbyrne    schedule 14.11.2012
comment
Работает ли CodePro AnalytiX под 4.2 (Juno)? - person erickson; 15.11.2012
comment
@erickson не уверен ... моя компания использует собственную версию Eclipse, поэтому мне давно не приходилось использовать vanilla Eclipse. - person dbyrne; 15.11.2012

Из списка FindBugs описаний ошибок:

ST: запись в статическое поле из метода экземпляра (ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD)

Этот метод экземпляра записывает в статическое поле. Это сложно исправить, если манипулируют несколькими экземплярами, и, как правило, это плохая практика.

Аналогичного описания ошибки для доступа к статическому полю через статический метод, вызываемый из метода экземпляра, нет.

Вы можете обсудить обоснование этого решения в списке рассылки.

person barrowc    schedule 14.11.2012