0

プログラムに次のコードがあります。

...
private void generateStack() {
    List<AdvertisementsModel> adsForModel = Storage.getAdsForId(model.getId());
    ...
    adsForModel.clear();
...

Storage静的フィールドとメソッドを持つ静的クラスです。generateStackメソッドは別のクラスにあり、インスタンスオブジェクトにあります。参照が最終的でない場合、なぜクラスadsForModel.clear();のリストに影響を与えるのですか?StorageasdForModel

4

4 に答える 4

3

Storage.getAdsForId(...)List同じオブジェクトへの参照のコピーを返します。したがって、この参照を介した呼び出しは同じリストに影響します。呼び出すStorage.getAdsForIdと、新しいリストは作成されません。同じリストへの新しい参照が作成されるだけです。

したがって、明示的に返すかImmutableList、リストの防御的なコピーを作成してコピーをStorage.getAdsForId(...)返すことをお勧めします。

が可変の場合はディープ コピーを作成する必要があることに注意してください。そうしないAdvertisementsModelと、別のレベルで同じ問題が発生します。(そうしないと、リストのコピーができても、両方のリストに同じAdvertisementsModelオブジェクトへの参照が含まれていて、それらを変更すると、内部のリストの内容に影響が及ぶ可能性がありますStorage。)

于 2013-03-04T10:07:05.770 に答える
3

Java は (参照の) 値渡しです。Storage.getAdsForId(model.getId())そのため、ストレージ内に静的に格納されている参照を返す場合clear()、インスタンスでそれを呼び出すと、その中の同じリストにも影響しStorageます。代わりにこれを行うことができます:

return new ArrayList<AdvertisementsModel>(Storage.getAdsForId(model.getId()));

代わりにリストのコピーを返すことで、ストレージ内のリストへの影響を回避できます。もちろん、このリストの要素を変更しても、 のリスト内にある同じ要素に影響しStorageます。それを避けるには、リスト内の各要素をディープ コピーする必要があります。

于 2013-03-04T10:10:12.217 に答える
1

getAdsForIdリストのコピーを返す必要があります。それ以外の場合は参照を返し、リストを呼び出すとclear元のリストが空になります。

于 2013-03-04T10:07:27.917 に答える
1

それが最終的なものである場合、元のリストは影響を受けませんか? 私はそれについて疑問を持っています...それは同じリストインスタンスです。このために、私はどちらかを使用します

new ArrayList<AdvertisementsModel>(Storage.getAdsForId(model.getId()));

新しいリスト インスタンスを作成し、Storage可能であれば元のリストの UnmofifiableList を返すようにクラスを変更します。

return Collections.unmodifiableList(adsForIdList);

このソリューションは呼び出しごとに新しい List インスタンスを作成しないため、これを希望します。作成する必要があるかどうかを決定するのは受信コードの責任です。ただし、マルチスレッド環境では、元のリストが変更される可能性がある場合、これによりConcurrentModificationExceptions が発生する可能性があります。その場合、ゲッター自体でリストの「防御コピー」を作成する方が賢明です。コピーを変更しても元のリストには影響しないことに注意してください...

于 2013-03-04T10:11:33.887 に答える