2

次のように、変更不可能なリストを返すゲッターがあります。

public List<Product> getProductList() {
    if (productList == null)
        return new ArrayList<>();
    return Collections.unmodifiableList(productList);
}

私はこのゲッターを次のように呼んでいます:

List<Product> productList = new ArrayList<>(report.getProductList());

次に、このリストを次のように変更する別のメソッドに渡します。

for (Product product : productList) {
    product.addToAdvisoryList(advisory);
}

addToAdvisoryList(Advisory advisory) は次のとおりです。

public void addToAdvisoryList(Advisory advisory) {
    if (advisoryList == null) {
        setAdvisoryList(Collections.singletonList(advisory));
    } else if (!isContainedAdvisory(advisoryList, advisory)) {
        List<Advisory> newAdvisoryList = new ArrayList<>(advisoryList);
        newAdvisoryList.add(advisory);
        setAdvisoryList(newAdvisoryList);
    }
}

これらのコードを実行すると、元の製品リストが変更されます。誰かが正確に何が起こったのか説明してもらえますか? また、変更不可能なリストを変更しないようにするにはどうすればよいでしょうか?

4

2 に答える 2

0

あなたが提供したコードでは、元の (変更不可能な) リストが、変更可能なリストである a のコンストラクターに引数として渡されjava.util.ArrayListます。

List<Advisory> newAdvisoryList = new ArrayList<>(advisoryList);

Collectionこのコンストラクターは、指定された のすべての項目をそのイテレーターによって返された順序で含む新しいリストを作成します (ドキュメントを参照してください)。

製品のリストでも同じことが起こります。

List<Product> productList = new ArrayList<>(report.getProductList());

これにより、最初に変更不可能なリストを返すことは冗長になります。

つまり、変更不可能なリストを変更しているのではありません。変更不可能な(不変)リストの要素を使用して、変更可能な新しいリストを作成し、(変更可能な)リストを変更しています。

Java ドキュメントの不変リストについては、こちらも参照してください。UnsupportedOperationException不変リストを変更しようとすると、 が返されます。

編集

ゲッターに関する質問に答えるには:

「getter の目的は、オブジェクトの読み取り専用コピーを返すことではありませんか?」

ゲッターは、プライベートまたは保護されたクラス メンバーへの外部からのアクセスを提供するために使用されます。

あなたのようなクラスがある場合(あなたの例では)Report

public class Report {

    private List<Product> products;

    public void setProducts(List<Product> products) {
        this.products = products;
    }

    public List<Product> getProducts() {
        return products;
    }

}

これgetProductsにより、クラスの外部からリストにアクセスできるようになります (変更可能な場合は、要素を追加または削除できます)。この種のことは通常、Java Bean で行われますが、その使用については議論されています (ゲッターとセッターを不必要に状態情報を公開しないメソッドに置き換えることを検討してください)。いずれにせよ、Oracle によるゲッターとセッターの詳細については、こちらを参照してください。

于 2018-07-09T19:57:27.130 に答える