2016-06-28 3 views
0

...ので、私はそれを試してみました警告を消した。例えば、私は、このコンストラクタ</p> <pre><code>public Example(byte[] bytes) { this.bytes = bytes; } </code></pre> <p>とFindBugsのを実行した後、それは私が代わりにそれをクローン化を検討すべきであると言うだろうを持っているので、パラメータまたはクローンを通じてバイト配列値を代入FindBugsの()

public Example(byte[] bytes) { 
    this.bytes = bytes.clone(); 
} 

しかし、この種の変更には何らかの影響があるか否か、または否定的な副作用があるかどうかを知りたいと思います。私の理解から、これはbyte []だけでなく、すべての配列にも当てはまります。

おかげ

+0

メモリ使用量が増え、パフォーマンスが低下します。 – Codebender

答えて

2

可能性のあるバグは、インスタンスで配列を再利用すると、呼び出しコードと結合されます。つまり、配列に行われた変更はすべてその副作用を伴う可能性があります。

例:

char[] chars = new char[]{ 'a', 'b', 'c', ..., 'z' }; 
Alphabet lower = new Alphabet(chars); 

for(int i = 0; i < chars.length; i++) { 
    chars[i] = Character.toUpperCase(chars[i]); 
} 
Alphabet upper = new Alphabet(chars); 

配列がAlphabet内部で再利用された場合(つまり、複製されません)あなたは小文字でlower取引が、それは本当に、その要素が自分の大文字に置き換えられているアレイを使用している間と思うかもしれませんカウンターパート。

したがって、ほとんどの場合、配列のコピーを作成する方が安全です。それにはclone()を呼び出してください(他の方法もあります)。

これは、メモリの使用量が増えていることと、コピーを実行するためのパフォーマンスコストがあることです(いずれも少数の小さなアレイでは無視されますが、アレイのサイズや数が増えると増加します) 。

もう1つの弱点呼び出しコードが配列を共有すると予想され、クローンを作成するとそのコードが破損することがあります。それもチェックしなければなりません。

+0

ありがとう!私はこの事実をもっと理解しました。 – mugiwara528

0

は、アイデアは、アレイへの以降の更新がExampleオブジェクトにライトスルーしないように、守備のコピーを取ることです。また、配列への参照を保持していないので、ガベージコレクションに役立ちます。

この意味では、アレイを2回保存する可能性があるため、メモリを増やす可能性があります。

1

これは非常に一般的な状況です。いくつかの「外側」の配列やリストに依存するオブジェクトを作成する場合、そのオブジェクトは既存の参照を単に再利用する必要があります。またはその入力データのコピーを作成する必要がありますか?

再使用の意味:コピー操作にCPUサイクルを費やすことはありません。そして、明らかにメモリを再利用します(2,3の代わりに1つのコピー)

一方、参照を保持し、他の誰かがその "外部"のものを更新するとき。その参照を保持するすべてのオブジェクトも同様に影響を受ける可能性があります。

この意味では、主に設計上の観点から「最良」に基づいてこれらの2つのオプションのバランスをとる必要があります。一般に、多くの人々は現在、不変のクラス/オブジェクトを実装しようとしています。意味:作成時に、オブジェクトの「内容」は決して再び変化しません。言い換えれば、の不変に行きたい場合は、 "防御的なコピー"にする必要があります。しかし、そこから得るべきことがたくさんあります。

関連する問題

 関連する問題