2

システムで「イベント」の不変の表現を作成しているので、コンストラクターで渡された所有者のリストについては、それらの読み取り専用ビューを取得したいと思います。さらに、リストに渡されnullた場合は、その場合は読み取り専用の空のリストを作成したいと思います。

さて、でCollections.unmodifiableListボークするnullので、私は現在これを持っています:

userOwners_ = Collections.unmodifiableList(userOwners != null 
                                           ? userOwners 
                                           : new ArrayList<String>(0));

しかし、それは少し醜く非効率的なようです。Javaでこれを行うためのよりエレガントな方法はありますか?

4

4 に答える 4

6

Collections.emptyList()。しかし、真剣に、nullNPEする必要があります。

于 2013-02-20T03:19:50.767 に答える
3

同様に醜いですが、わずかに効率的な答えは

userOwners_ = userOwners != null ? 
                  Collections.unmodifiableList(userOwners) :
                  Collections.emptyList();

ただし、他にも注意すべき点がいくつかあります。

  1. ある時点で、誰かがnull空のリストを表すために使用することを決定したようです。それは貧弱な設計です...そして特別な取り扱いの必要性をもたらします。新しいリストに設定するかemptyList()、リストが常に空であることがわかっている場合は、設定することをお勧めします。

  2. nullそれが空のリストを表す方法であると意識的に決定していない場合、それnullは「予期しない」ものであり、原因を突き止めて修正できるように、NPEをスローさせる必要があります。(それはあなたが他の場所で初期化されていると仮定した変数かもしれません...しかしそうではありません。それはバグです。)

  3. 「読み取り専用」リストと「不変」リストのどちらが必要かについては、いくつかの混乱があります。

    • このunmodifiableList()メソッドは、変更できないリストを提供します。つまり、「読み取り専用」です。ただし、元のリストは引き続き変更でき、それらの変更は「読み取り専用」ラッパーを介して表示されます。
    • 「不変」リスト(つまり、まったく変更できないリスト)が必要な場合はclone()、元のリストに移動してから、を使用してクローンをラップする必要がありますunmodifiableList()
    • これらのどちらも、リストの要素(「所有者」オブジェクト)を不変にすることはありません(まだ不変でない場合)。
  4. 識別子userOwners_は、最も広く受け入れられている/使用されているJavaスタイルガイドのコードスタイル違反です。

于 2013-02-20T03:20:11.983 に答える
1

結果のuserOwners_は引き続き変更可能です。userOwnersへの変更はすべてuserOwners_の一部になります。

そのメンバー変数を本当に不変にしたい場合、これを行う正しい方法は次のとおりです。

private final List<String> userOwners;

public MyObject(List<String> userOwners){
  this.userOwners = userOwners != null ? Collections.unmodifiableList(new ArrayList<String>(userOwners)) : Collections.emptyList();
}

マイナーな点として、メンバー変数の命名はJavaスタイルのガイドラインに従っていません(userOwners_は、Javaコードを定期的に読む私たちにとって奇妙です)

別の投稿者が書いたことを拡張するには:パブリックメソッドへのnull入力を受け入れる前に(NPEをスローせずに)、本当に、本当によく考えてください。この種の振る舞いはバグを隠すことができます-速く失敗し、発信者に彼らが何をしているのかを考えさせる方がはるかに良いです。

于 2013-02-20T03:16:57.987 に答える
1

私の好みの方法はGuavaを使用することです:

this.userOwners = ImmutableList.copyOf(Preconditions.checkNotNull(userOwners));

タックラインの答えのように、これもnullを空のリストに黙って変換するのではなく、例外をスローします。

ここでの他の回答とは異なり、を使用ImmutableList.copyOf()すると、発信者が後で変更できるリストを渡さないようになります。

于 2013-02-20T03:23:16.250 に答える