35

implementsと extendsのjava.util.ArrayList実装。しかし、Java ドキュメントでは、AbstractList がすでに List を実装していることがわかります。それでは、List を実装して AbstractList を拡張するのは冗長ではありませんか? 私の2番目の質問 次のコードを見てください:ListAbstractList



String str = "1,2,3,4,5,6,7,8,9,10";
String[] stra = str.split(",");
List<String> a = Arrays.asList(stra);

Arrays クラスのArrays.asList()メソッドには、ArrayList の独自の実装が含まれています。しかし、これは AbstractList を拡張するだけで、List を実装していません。しかし、上記のコードはコンパイルされます。
しかし、コードが次のように変更された場合

String str = "1,2,3,4,5,6,7,8,9,10";
String[] stra = str.split(",");
java.util.ArrayList<String> a = Arrays.asList(stra);

エラーが表示されます:cannot convert form List<String> to ArrayList<String>
この背後にある理由は何ですか?
EDIT
Arrays.asList()は ArrayList の独自の実装を返します。これをチェックしてください。

4

8 に答える 8

29

それでは、List を実装して AbstractList を拡張するのは冗長ではありませんか?

はい、100% 冗長です。ただし、Java の実装者は、コレクション ライブラリのすべてのパブリック実装で非常に一貫してインターフェイスを追加しました。

  • LinkedList<E>そしてwhich implementsをArrayList<E>拡張してから、自分自身を実装します。AbstractList<E>List<E>List<E>
  • HashSet<E>そしてwhich implementsをTreeSet<E>拡張してから、自分自身を実装します。AbstractSet<E>Set<E>Set<E>
  • HashMap<K,V>そしてwhich implementsをTreeMap<E>拡張してから、自分自身を実装します。AbstractMap<K,V>Map<K,V>Map<K,V>

私の理解では、彼らはドキュメンテーションの目的でそうしArrayList<E>たのList<E>です。ArrayList<E>拡張するという事実AbstractList<E>は、その実装のそれほど重要ではない詳細です。他のパブリック コレクション タイプについても同様です。

クラスは公開されていないため、その作成者は明示的に含めることを気にしませArrays.ArrayList<E>んでした。List<T>

Arrays.ArrayList<E>内部クラスと public クラスArrayList<E>は互いに無関係であるため、変換の失敗に関する限り、これは驚くべきことではありません。

于 2013-09-01T12:57:55.450 に答える
4

Arrays.asListはListを返します。そのため、 ArrayListにキャストするのは安全ではありません。返されるListのタイプがわからないためです(リストの作成元の配列タイプによって異なります)。2 番目のスニペットでは、暗黙的にArrayListが必要です。したがって、 Listが必要なため、最初のスニペットが正常にコンパイルされている間は失敗します。できるよ-

ArrayList<String> a = new ArrayList<String>(Arrays.asList(stra));
于 2013-09-01T12:45:48.470 に答える
3

理由があると思います。これは私の考えであり、JLSのどこにも見つかりませんでした。

私が広く使用される API を作成している開発者である場合、なぜこれを行うのでしょうか?

これを行う理由はまったくありませんが、インターフェースを作成し、インターフェースの実装をList提供したこのシナリオを考えてみてください。ArrayListList

私はまだ抽象クラスを書いていませんAbstractList

ある日、要件が発生し、インターフェイスの実装をさらにいくつか書くように求められました。これらの実装のほとんどは、インターフェイスのメソッドListに対して類似または同じ具体的なメソッドを持っています。abstractList

先に進み、AbstractListこれらすべてのメソッドに必要な実装を記述します。Listしかし今、私は自分のクラスの半分がインターフェイスを実装し、半分が拡張するのが好きではありませんAbstractList

また、以前に書いたクラスから 'implements List` を単純に削除することはできません。おそらく、今が適切な時期ではないか、他の人のコードが私の新しいリリースで壊れてほしくないからです。

これはあくまでも私の意見です。

于 2013-09-01T14:46:44.513 に答える