web-dev-qa-db-ja.com

PMD:ループ内での新しいオブジェクトのインスタンス化を回避

PMDルールに問題がありますAvoid instantiating new objects inside loops。ここにいくつかのサンプルコードがあります:

import Java.awt.Dimension;

public class PMDDemo {
    public static void main(final String[] args) {
        final Dimension[] arr = new Dimension[10];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = new Dimension(i, i); // rule violation here
        }
    }
}

PMDは、コード内のマークされた場所で上記のルール違反を発生させます。ループ内で作成せずに、クラスのインスタンスnを作成するにはどうすればよいですか?

onlyOneExitルールのように、PMDのルールの一部が物議を醸していることを知っています。しかし、今までは少なくともその背後にある考えを理解していました。このルールの根拠はわかりません。誰かが私を助けてくれますか?

22
brimborium

特定のユースケースでは、新しいオブジェクトへの参照を維持するため、意味がありませんafterループ。したがって、ソリューションに代わる実際の手段はありません。

より一般的に言えば、 Javaは安価です)で短期間のオブジェクトを作成する *(GCがより頻繁に実行するという隠れたコストは別として)。特に、割り当てはほとんど自由であり、GCの時間はほとんど到達可能なオブジェクトの量に依存します-死んだオブジェクトは典型的なGCアルゴリズムのGC時間を増加させません。

JITは、不要なオブジェクトが作成されたことを検出した場合、さまざまな最適化を実行することもできます。

明らかに、役に立たないものを作成することはお勧めしませんが、オブジェクトを再利用しようとすると、逆効果になることがよくあります。

実用的な例として、ループ内で新しいセットを作成する方が、ループの前にセットを作成して各反復でそれをクリアするよりも安価であることを示す this post を見ることができます。

*リンクをありがとう@RichardTingle

26
assylias
for (int i = 0; i < arr.length; i++) {
  arr[i] = new Dimension(i, i); // rule violation here
}

上記のPmdは、

 for (int i = 0; i < arr.length; i++) {
   arr[i] = createNewDimension(i,i); // rule violation here
 }

 private static Dimension createNewDimension(i,i) {
   return new Dimension(i, i);
 }

ループ内でnew演算子を直接使用しないでください。これをプライベートメソッド内に移動するだけです。

0