4

オブジェクトを作成し、静的変数でオブジェクトの数を追跡するクラスがあるとします。このようなもの:

public class Apple {
    private static int count = 0;

    public Apple () {
        count++;
    } 

    public void removeApple() {
        count--;
    }
}

このコードを FindBugs でチェックするとWrite to static field from instance method、もちろん明らかな警告が表示されます。

この問題を回避してより安全にし、FindBugs 警告を取り除くにはどうすればよいですか??

4

4 に答える 4

9

1. 一般的なプログラミングのアドバイス

このメッセージは、静的変数とインスタンス変数のスコープの違いを認識していない初心者プログラマーにとって一般的な落とし穴であるため、潜在的なプログラミングの間違いについて警告するためにあります。

removeAppleただし、コンパイラ エラーを発生させずにメソッドの実際のバージョンを宣言できる場合は、staticおそらく宣言する必要があります。これにより、警告が処理され、このメソッドがクラスの特定のインスタンスとは何の関係もないことが明確になります。

2. 並行性に関する懸念事項

この警告のもう 1 つの側面は、スレッドの安全性に関するものです。インスタンスからフィールドに書き込むと、staticスレッド間でクラス インスタンスを共有しなくても、異なるスレッドから同時更新を行う可能性が開かれます。

コードにスレッド セーフが必要ない場合 (一般的には問題ありません)、何もする必要はありません。必要な場合は、フィールドのすべての更新を同期するか、AtomicIntegerラッパーを使用してください。

個人的には、AtomicIntegerそれが最も安全なオプションであるため、選択します。他のオプションでは、クラスのすべてのフィールド更新を追跡し、それらが同期されていることを確認する必要があります。使い方AtomicIntegerはとても簡単です:

private static final AtomicInteger count = new AtomicInteger();

count.getAndIncrement()の代わりに使用しますcount++

于 2013-07-02T10:07:06.470 に答える
3

プリミティブAtomicIntegerの代わりに使用します。int

メソッドを同期する場合があります。

于 2013-07-02T10:03:57.700 に答える
1

次の 2 つの選択肢があります。

  1. duffmyoで言及されているように AtomicInteger を使用する

AtomicInteger は、アトミックにスレッドセーフなインクリメント カウンターなどのアプリケーションで使用されます。

また

2. 変数のアクセスを同期ブロックで制御する

そして、Findbug エラー除去の観点から:

論理的には、インスタンス メソッドがそのインスタンスのデータに影響を与えることを期待しています。静的メソッドが静的データに影響を与えることを期待しています。

カウンターを非公開にし、公開の getter メソッドと setter メソッドを提供すると、findbug エラーが取り除かれます。

于 2013-07-02T10:05:25.187 に答える
1

おそらく、FindBugs は removeApple() が static であることを好むでしょう。

于 2013-07-02T10:08:52.040 に答える