3

プロジェクトでFindbugツールを実行したところ、次のタイプの18の問題が見つかりました。

可変オブジェクトへの参照の保存->可変オブジェクトへの参照を組み込むことにより、内部表現を公開できます

したがって、コンストラクターがObject型の配列を受け入れ、それをプライベートクラスのメンバー変数に割り当てるクラスがあります。次に例を示します。

public Class HtmlCellsProcessing extends HtmlTableProcessing
{
    private Object[] htmlCells;

    public HtmlCellsProcessing(Object[] htmlCells)
    {
        this.htmlCells = htmlCells;
    }
}

警告についての詳細は次のとおりです。

このコードは、外部で変更可能なオブジェクトへの参照をオブジェクトの内部表現に格納します。信頼できないコードによってインスタンスにアクセスし、変更可能なオブジェクトへのチェックされていない変更がセキュリティやその他の重要なプロパティを危険にさらす場合は、別のことを行う必要があります。オブジェクトのコピーを保存することは、多くの状況でより良いアプローチです。

彼らが私に与えるアドバイスは非常に明白ですが、配列のサイズが非常に大きく、その値をメンバー変数配列にコピーすると、アプリケーションは2倍のメモリを消費することになります。

大量のデータがあるようなシナリオではどうすればよいですか?参照として渡す必要がありますか、それとも常にコピーする必要がありますか?

4

4 に答える 4

2

場合によります。スペース、時間、正確さなど、複数の懸念があります。

防御コピーは、配列を保持しているクラスの知識がなくてもリスト項目が変更されないことを保証するのに役立ちます。ただし、O(n)の時間とスペースが必要になります。

非常に大きなアレイの場合、空間と時間の防御コピーのコストがアプリケーションに有害であることに気付くかもしれません。配列にアクセスしてすべてのコードを制御する場合は、防御的なコピーなしで正確性を保証し、そのクラスでのFindBugs警告を抑制することが合理的である可能性があります。

于 2013-03-25T22:07:52.777 に答える
1

グアバライブラリの不変リストを試してみることをお勧めします。http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplainedを参照してください

于 2013-03-25T21:30:48.593 に答える
1

カプセル化とパフォーマンスの両方が必要な場合、一般的な解決策は、代わりに不変オブジェクトへの参照を渡すことです。

したがって、巨大な配列を直接渡すのではなく、配列の変更を許可しないオブジェクトにカプセル化します。

final class ArraySnapshot {
    final Object[] array;

    ArraySnapshot(Object[] array) {
        this.array = Arrays.copyOf(array);
    }

    // methods to read from the array
}

このオブジェクトは安価に渡すことができるようになりましたが、不変であるため、カプセル化が保証されます。

もちろん、このアイデアは、新しいことではないにしても、それが何をするのかというStringことですchar[]

于 2013-03-25T21:33:47.950 に答える
0

彼らが私に与えるアドバイスは非常に明白ですが、配列のサイズが非常に大きく、その値をメンバー変数配列にコピーすると、アプリケーションは2倍のメモリを消費することになります。

Javaでは、ディープコピーを行わない限り、参照自体をオブジェクトではなくコピーします。
したがって、警告を取り除くことが唯一の懸念事項である場合(これは有効ですが、実際に何を格納するかを理解しておらず、オブジェクトを変更する複数のスレッドがある場合は特に有効です)、メモリをあまり気にせずにコピーを実行できます。

于 2013-03-25T21:34:22.557 に答える