15

私は Java の機能に感銘を受けており、次の問題のために Java の使用をあきらめたくありません。

継承される可能性のあるクラスがあり、その内部はprivate ArrayList arr;セッター関数は問題ありませんが、ゲッター関数return arr;はその変数への参照を返します.意味がありません!

C ++ではreturn const arr;、変数への定数参照を返すだけです。

必要な計算が非常に多いため、変数を複製したり手動でコピーしたりしないようにする必要があります(変数のみを読み取る)なぜjavaにconstが返されないのですか???? コピーから逃れる方法はありますか?

ps(final ArrayList<Integer> arr;)は、配列が常にサイズまたは要素の値を変更するため、オプションではありません。

その修正が見つからない場合は、C++ に戻るか、すべてを公開すると脅迫しています。私のソフトウェアを決して入手しないでください :D


編集:もう1つの重要な質問:私は何か良くないことを求めていますか(ソフトウェアエンジニアリングの観点から)、Javaの作成者がconst参照を持たない(読み取り専用参照を返す)と考えていた場合、他の方法で処理できる何かを求めているに違いありません仕方。または私のプログラム設計が間違っているので、私はとても混乱しています。

4

4 に答える 4

23

戻り値をjava.util.Collections.unmodifiableListでラップします。データのコピーは作成しませんが、元のリストをラップし、読み取り専用操作を基になるリストに委任します。リストを変更する操作は、実行時に拒否されますUnsupportedOperationException

君の

return arrayList;

になる

return Collections.unmodifiableList(arrayList);

残念ながら、読み取り専用の制約はコンパイラによって強制されません。ただし、これらは実行時に適用されます。

unmodifiableSetunmodifiableMapunmodifiableCollectionunmodifiableSortedSet、およびunmodifiableSortedMapも利用できます。これらが十分でない場合でも、この一般的な設計アプローチからインスピレーションを得て、独自のカスタムの読み取り専用ラッパー クラスを作成できます。

于 2010-11-24T00:31:36.443 に答える
2

:) いくつかのオプションがあります。

  • ゲッターを公開せず、呼び出しが許可されているメソッドのみを提供します。

    public void addToList(Object arg) { this.arr.add(arg);}

  • 不変オブジェクトを返す:

    public List getArr() { return Collections.unmodifiableList(this.arr); }

于 2010-11-24T00:49:37.923 に答える
0

Google Guavaの不変コレクションを使用することもできます。この場合、フィールドにImmutableListを格納します。

もちろん、クラスがこのリストを内部的に変更する必要がある場合、新しい ImmutableList インスタンスを作成し、毎回フィールドに再割り当てする必要があるため、 ImmutableList を使用するのは悪い考えになる可能性があります...

しかし、オブジェクトの構築後に List が変更されないことがわかっている場合は完璧です。

不変の例 (オブジェクトの構築後にリストは変更されません)

@Immutable
public final class Foo {

    @Nonnull
    private final ImmutableList<String> list;

    public Foo(@Nonnull List<String> list) {
        // you could also compute the appropriate list here
        // before assigning it to the field
        this.list = ImmutableList.copyOf(list);
    }


    public ImmutableList<String> getList() {
        return list;
    }
}

変更可能な例 (リストはセッターを使用してのみ変更できます)

public class Foo {

    @Nonnull
    private ImmutableList<String> list = ImmutableList.of();

    public ImmutableList<String> getList() {
        return list;
    }

    public void setList(@Nonnull List<String> list) {
        this.list = ImmutableList.copyOf(list);
    }
}

備考

  • メソッドが可能な限り最も一般的な型を返すようにすることをお勧めすることが多いことは知っていますが (Listこの場合)、getter の戻り値の型を として宣言することを好みImmutableListます。および API コントラクトとして。「このリストが不変であることを保証します。心配したり、防御的にコピーしたりする必要はありません」と言っているようなものです。そして、それは非常に簡潔です。
  • ImmutableList.copyOf()nullリストを自動的に拒否するため(をスローすることによりNullPointerException)、素晴らしいです。また、null 要素も拒否します。また、ソース リストがすでに ImmutableList である場合はコピーしません。これにより、無駄なオブジェクトのインスタンス化が回避されます。
  • 2 番目の例では、 を使用してフィールドを空の ImmutableList に初期化します。これは、null 値 ( Null オブジェクト パターンImmutableList.of())の代わりに空のコレクションを返すことをお勧めするためです。これにより不要なオブジェクトのインスタンス化が作成されると思われるかもしれませんが、実際にはシングルトンが返されます。ImmutableList.of()
于 2011-03-19T13:14:26.323 に答える
-1

unmodizableListは間違いなく答えです。

于 2010-11-24T01:52:09.633 に答える