なぜかJava.util.ArrayList
はnull
を追加できます。 null
をArrayList
に追加したい場合はありますか?
プロジェクトで、いくつかのコードがnull
をArrayList
に追加するバグがあり、バグがどこにあるのかを見つけるのが難しいため、この質問をします。明らかにNullPointerException
がスローされましたが、他のコードが要素にアクセスしようとするまではスローされませんでした。問題は、null
オブジェクトを追加したコードを見つける方法でした。要素が追加されているコードでArrayList
が例外をスローした方が簡単だったでしょう。
この設計上の決定は、主に命名によって行われているようです。
名前ArrayListは、読者にarraysと同様の機能を提案します-そして自然な Java Collections Framework 設計者は、大部分のAPIユーザーが配列と同様に機能することに依存することを期待するでしょう。
特に、これにはnull要素の処理が含まれます。以下が正常に機能することを知っているAPIユーザー:
array[0] = null; // NPE won't happen here
arrayListの同様のコードがNPEをスローするかどうかを調べるには、 かなり驚いた になります。
arrayList.set(0, null); // NPE => WTF?
上記のような推論は JCFチュートリアル ArrayListとプレーン配列の類似性を示唆する強調ポイントに示されています。
ArrayList ...は一定時間の位置アクセスを提供し、非常に高速です...
Nullを許可しないList実装が必要な場合は、APIユーザーの混乱を避けるために、NonNullableArrayList
などのように呼び出すことをお勧めします。
付記以下のコメントに補足説明があり、追加の考慮事項ここで説明されている推論をサポートしています。
Nullは、リストの要素の有効な値である可能性があります。リストに、ユーザーのリストに関するオプションのデータを表す要素が含まれ、ユーザーと同じ順序で保存されているとします。追加データが入力されている場合、リストには追加データが含まれます。そうでない場合、ユーザーに対応するスロットはnullになります。 (私はもっと良い例があると確信していますが、あなたはアイデアを理解します)
nullの追加を許可したくない場合は、nullが追加されたときにスローする独自のラッパーで配列リストをラップできます。
ArrayList
は、意図的にnullを許可します。それは意図的なものです。 javadoc から:
「[ArrayListは] Listインターフェースのサイズ変更可能な配列の実装です。オプションのリスト操作をすべて実装し、すべての要素を許可しますnullを含む。」
「なぜ」に対する答えは、リストにnull
を配置する必要がある場合、ArrayListが使用できない場合は使用できないということです。対照的に、値を追加する前に値をテストするか、これを防ぐラッパーを使用することにより、ArrayListにnullが含まれないようにすることができます。
ArrayListにnullを追加したい場合はありますか?
明らかに、null
に明確な意味がある場合。たとえば、リスト内の指定された位置の値が初期化または提供されていないことを意味する場合があります。
要素が追加されているコードでArrayListが例外をスローした方が簡単だったでしょう。
ラッパークラスを作成することで、その動作を簡単に実装できます。ただし、これはmostプログラマ/アプリケーションが必要とする動作ではありません。
nullをArrayListに追加したい場合はありますか?
確かに、事前割り当てはどうですか?十分な情報がないため、まだ作成できないもののArrayList
が必要です。誰かが何かをしたいと思うかもしれない理由を考えることができないからといって、それが悪い考えになるわけではありません。なんでも。 (今、誰かがやって来て、代わりに、いくつかのあいまいなブログで読んだあるパターンを満たす空のオブジェクトを用意し、プログラマがif
ステートメントを使用せずにプログラムを書くことができるはずだと言うでしょう、何とか何とか。)
コンテナにnull
sがあってはならないという契約がある場合、契約を確実に守ることは、おそらくアサートによって最も適切なことです。おそらく、最大10行のコードが必要になります。 Javaを使用すると、この種のことを非常に簡単に行うことができます。JDKはあなたの心を読み取ることができません。
これは、ここでは(ソフトウェア)哲学的な質問のようです。
ユーティリティクラスとしてのArrayList
は、考えられるユースケースの幅広いコンテキストで役立つように設計されています。
Nullを有効な値として受け入れることは推奨されないという隠れた主張に反して、null値が完全に合法である多くの例があります。
最も重要な理由の1つは、null
が、フレームワークタイプを含むすべての参照タイプと同等のdo not know
であることです。これは、どんな場合でもnullをnothing
値のより流暢なバージョンに置き換えることができないことを意味します。
したがって、Integer 1、3、7を対応するインデックスの配列リストに格納するとします。何らかの計算のために、インデックス5の要素を取得したいので、配列が返す値は「値が格納されていません」です。これは、nullまたは NullObject を返すことで実現できます。ほとんどの場合、組み込みのnull値を返すことで十分に表現力が高まります。 canがnullを返すメソッドを呼び出し、その戻り値を使用して、戻り値のnullに対するチェックが最新のコードで非常に一般的です。
ステートメント
File f = null;
有効で便利です(理由を説明する必要はないと思います)。同様に、いくつかのファイルがnullの可能性があるファイルのコレクションがあると便利です。
List<File> files = new ArrayList<File>();
// use my collection of files
// ....
// not using this one anymore:
files.set(3, null);
Nullオブジェクトを含む可能性のあるコレクションの有用性は、nullの可能性があるオブジェクトの有用性から直接進みます。それは本当にそれと同じくらい簡単です。
制限的であるというよりは、すべてを受け入れる方が簡単であり、事実の後にデザインを開くことを試みます。
たとえば、Oracle/SunがNonNullableArrayListのみを提供していて、リストにNullを追加できるようにしたいとしたらどうでしょう。どうしますかおそらく、まったく異なるオブジェクトを作成する必要があります。NonNullableArrayListの拡張を使用することはできません。代わりに、すべてを取得するArrayListがある場合は、それを簡単に拡張して、null値を受け入れないaddをオーバーライドできます。