4

ワイルドカードを含むリストを受け取るメソッドを使用できるのはなぜですか。

public processGenerics(List<? extends User> users){...}

しかし、同じリストを同様の方法でインスタンス化することはできませんか?

List<? extends User> alist = new ArrayList<? extends User>();

[編集済み、元の質問の一部ではありませんが、関連性があります]通常の継承と同じ方法でコレクションを使用してキャストできないのはなぜですか。

List<User> users = new ArrayList<Admin>();
4

4 に答える 4

4

構成:

List<? extends User> user

のインスタンスを保持できる変数を意味します。List<T>ここで、Tはユーザーの不明なサブタイプです。実際にインスタンス化するときArrayList<T>は、それが保持することになっているタイプを常に知っているので、そこでこの不確実性を表現させることは役に立ちません。

別の言い方をすれば、変数は(潜在的に)多くの異なるタイプのオブジェクトを保持できます。オブジェクトインスタンスは、それ自体の1つのタイプのみです。そのため、変数宣言はより柔軟でなければなりません。

于 2012-09-28T11:13:56.533 に答える
4

問題の最も紛らわしい側面は、ジェネリック型とクラシック型のraw型で受けなければならない根本的なメンタルスイッチです。

Generics以前は、各変数にはObjectなどの明確な型がありました。文字列を割り当てることもできますが、文字列オブジェクトであるため、パラダイムが成り立ちます。すべての場合で、オブジェクトであるものをオブジェクト変数に割り当てます。

ジェネリックではそうではありません。宣言された変数型とは関係がないが、特定のパターンのみを満たす型List<? extends Number>の範囲から割り当てることができる、がある場合があります。パターンはワイルドカードで記述されます。instanceof

したがって、ジェネリック変数型について推論するときに生活を楽にするためには、明確な型の単純で居心地の良い概念を放棄し、これらの「型パターン」の観点から考える必要があります。

あなたの質問の2番目の部分に関しては:List<User>とが関連してList<Admin>いるという事実に関係なく、とは完全に無関係なタイプです。これがジェネリックスの仕組みであり、それには十分な理由があります。Javaでは、に追加することはできません。また、次のような事態が発生する可能性があります。UserAdminOrdinaryUserList<Admin>

List<User> users = new ArrayList<Admin>();
users.add(new OrdinaryUser()); // shouldn't be allowed!

正式な用語は、ジェネリック型は型パラメーターに関して不変であるということです。それはすでに非常によくカバーされているので、この用語のためにグーグルで回るのが最善です。

于 2012-09-28T11:23:17.253 に答える
3

ワイルドカードインスタンスをインスタンス化することはできません。特定のインスタンスのみをインスタンス化できます。例:

List<? extends User> alist1 = new ArrayList<User>();
List<? extends User> alist2 = new ArrayList<SubClassOfUser>();

意味List<? extends User>は、「コンパイル時に型が不明であるが、上限がUser-のいずれかUserまたはサブクラスであるリストUser」です。

変数は ワイルドカードで定義できますが、インスタンスはそうではありません-それは何かのリストでなければなりません

于 2012-09-28T11:12:49.830 に答える
-1

new演算子は、新しいオブジェクトにメモリを割り当て、そのメモリへの参照を返すことにより、クラスをインスタンス化します。オラクル

オブジェクトの作成にワイルドカードを使用する場合、割り当てるメモリの量を知ることはできません。

パラメータタイプとしてメソッドに渡すものには、メモリの割り当ては含まれません。

于 2012-09-28T11:47:31.803 に答える