1

私は何度も同じようなコードに遭遇します:

class AClass{
    private Iterable<String> list;
    public AClass(Iterable<String> list){ this.list = list; }
    ...
}

このコードでは、Iterableの参照がAClassに直接渡されます。最終結果は、リスト参照を外部に直接公開するのと同じです。AClass.listをfinalにしたとしても、AClassの外部からのコードがリストのコンテンツを変更することを許可しますが、これは悪いことです。

これに対抗するために、コンストラクターで防御コピーを実行します。

ただし、この種のコードは非常に一般的です。パフォーマンスの考慮に加えて、人々がこの種のコードを書く意図は何ですか?

4

5 に答える 5

1

簡単な答えです。それがあなた自身のコード/小さなチームである場合、この方法で物事を行う方が、多くの場合、より速く、より簡単で、メモリとCPUの負荷が少なくなります。また、何人かの人々はそれ以上のことを知らないだけです!

于 2012-12-12T06:44:04.457 に答える
1

おなじみのイディオムのコピーコンストラクターを確認することをお勧めします。

于 2012-12-12T07:01:47.953 に答える
1

そのパターンには何の問題もありません。クラスがリスト(または反復可能)を操作するオブジェクトを表す場合、そのリストをコンストラクターに提供するのは自然なことです。クラスが基になるコレクションへの変更を処理できない場合は、修正または文書化する必要があります。コレクションのコピーを作成することは、それを修正する1つの方法です。

もう1つのオプションは、不変のコレクションのみが許可されるようにインターフェイスを変更することです。

public AClass(ImmutableList<MyObject> objects) {
    this.objects = objects;
    ...

もちろん、ある種のImmutableListクラスまたはインターフェースが必要になります。

クラスの用途とユーザーによっては、既知の「弱点」を文書化することでコピーを作成しないようにすることもできます。

/**
 * ...
 * @param objects list of objects this AClass-object operates on.
 *                The list should not be modified during the lifetime 
 *                of this object
 */
public AClass(List<MyObject> objects) ...
于 2012-12-12T09:30:42.937 に答える
0

他の人があなたの値を変更できるという理由だけでなく、セキュリティ上の理由からも、コピーを作成することは常に良い習慣です。

于 2012-12-12T06:49:56.980 に答える
0

他の回答で指摘されているように、コードが内部で使用されている場合は、問題にはなりません。ただし、APIとして公開する場合は、次の2つのオプションがあります。

まず、防御コピーを作成してから返します

2つ目は、を作成してUnmodifiableCollection返し、コレクション内の何かを変更しようとすると例外が発生する可能性があるという事実を文書化することです。

ただし、最初のオプションの方が適しています。

于 2012-12-12T07:50:36.710 に答える