12

次のような Java クラスがあります。

public class Foo {

    public static int counter = 0;

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

counterFindBugsは、インスタンス メソッドによる静的フィールドへの書き込みについて警告します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 は文句を言いません。それは間違っていませんか?静的メソッドを介して、インスタンス メソッドから静的フィールドにまだ書き込みを行っていますね。

4

2 に答える 2

19

将来のある時点で、このセッター メソッドをスレッド セーフにする必要があると判断し、それを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 メソッドがより複雑なロジックを持ち、(1 つのインスタンス メソッドからだけでなく) 多くの異なる場所から呼び出される実際の例では、後者のパターンの方がリファクタリングが容易です。

余談ですが、私の意見では、Google の CodePro Analytixプラグインは、FindBugs よりもはるかに高速で包括的なツールです。

関連している:

于 2012-11-14T23:08:25.283 に答える
5

バグの説明の FindBugs リストから:

ST: インスタンス メソッドから静的フィールドに書き込む (ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD)

このインスタンス メソッドは、静的フィールドに書き込みます。複数のインスタンスが操作されている場合、これを正しく行うのは難しく、一般的に悪い習慣です。

インスタンス メソッドから呼び出された静的メソッドを介した静的フィールドへのアクセスに関する同様のバグの説明はありません。

FindBugsメーリング リストで、この決定の背後にある理論的根拠について話し合うことをお勧めします。

于 2012-11-14T23:12:40.080 に答える