[解決済み] List<? extends Number>データ構造に追加する方法は?
質問
私はこのように宣言されたリストを持っています。
List<? extends Number> foo3 = new ArrayList<Integer>();
foo3 に 3 を追加しようとしました。しかし、このようなエラーメッセージが表示されます。
The method add(capture#1-of ? extends Number) in the type List<capture#1-of ?
extends Number> is not applicable for the arguments (ExtendsNumber)
解決方法は?
申し訳ありませんが、できません。
のワイルドカード宣言は
List<? extends Number> foo3
は、変数
foo3
は、特定の型の値ではなく、ある型の系列から任意の値を保持することができます。つまり、これらのどれもが合法的な代入であることを意味する。
List<? extends Number> foo3 = new ArrayList<Number>(); // Number "extends" Number
List<? extends Number> foo3 = new ArrayList<Integer>(); // Integer extends Number
List<? extends Number> foo3 = new ArrayList<Double>(); // Double extends Number
では、このように考えると、どのようなオブジェクトを
List foo3
の後に続くものであれば、合法です。
ArrayList
の代入が必要です。
-
を追加することはできません。
Integer
なぜならfoo3
を指している可能性があります。List<Double>
. -
を追加することはできません。
Double
なぜならfoo3
を指している可能性があります。List<Integer>
. -
を追加することはできません。
Number
なぜならfoo3
を指している可能性があります。List<Integer>
.
にオブジェクトを追加することはできません。
List<? extends T>
がどのようなものかを保証できないからです。
List
を指しているので、そのオブジェクトがその
List
. 唯一の "保証" は、そこから読み取ることだけが可能で、そのためには
T
またはそのサブクラスである
T
.
逆の論理は
super
は、例えば
List<? super T>
. これらは合法です。
List<? super Number> foo3 = new ArrayList<Number>(); // Number is a "super" of Number
List<? super Number> foo3 = new ArrayList<Object>(); // Object is a "super" of Number
特定の型T(例.
Number
から
List<? super T>
がどのようなものであるかは保証できないからです。
List
を指していることになります。唯一の保証は
T
(のサブクラス)。
T
) を、指されたリストの整合性を損なうことなく使用することができます。
の署名がその典型例です。
Collections.copy()
:
public static <T> void copy(List<? super T> dest, List<? extends T> src)
がどのように
src
リスト宣言では
extends
を使えば、関連するリスト型のファミリーから任意のリストを渡すことができ、それでもT型またはTのサブクラスの値を生成することが保証されます。
src
のリストを作成します。
は、その
dest
リスト宣言では
super
を使えば、関連するリスト型のファミリーから任意のリストを渡すことができ、かつ、そのリストに特定の型Tの値を書き込むことができることが保証されます。しかし、これは
特定
型Tから読み出すと
ジェネリックワイルドカードのおかげで、このメソッド1つでこれらの呼び出しをすべて行えるようになったわけです。
// copy(dest, src)
Collections.copy(new ArrayList<Number>(), new ArrayList<Number>());
Collections.copy(new ArrayList<Number>(), new ArrayList<Integer>());
Collections.copy(new ArrayList<Object>(), new ArrayList<Number>());
Collections.copy(new ArrayList<Object>(), new ArrayList<Double>());
この紛らわしく、非常に幅の広いコードを頭の体操に考えてみてください。コメントアウトされた行は不正であり、その理由は行の右端に記載されています(スクロールしないと見れないものもあります)。
List<Number> listNumber_ListNumber = new ArrayList<Number>();
//List<Number> listNumber_ListInteger = new ArrayList<Integer>(); // error - can assign only exactly <Number>
//List<Number> listNumber_ListDouble = new ArrayList<Double>(); // error - can assign only exactly <Number>
List<? extends Number> listExtendsNumber_ListNumber = new ArrayList<Number>();
List<? extends Number> listExtendsNumber_ListInteger = new ArrayList<Integer>();
List<? extends Number> listExtendsNumber_ListDouble = new ArrayList<Double>();
List<? super Number> listSuperNumber_ListNumber = new ArrayList<Number>();
//List<? super Number> listSuperNumber_ListInteger = new ArrayList<Integer>(); // error - Integer is not superclass of Number
//List<? super Number> listSuperNumber_ListDouble = new ArrayList<Double>(); // error - Double is not superclass of Number
//List<Integer> listInteger_ListNumber = new ArrayList<Number>(); // error - can assign only exactly <Integer>
List<Integer> listInteger_ListInteger = new ArrayList<Integer>();
//List<Integer> listInteger_ListDouble = new ArrayList<Double>(); // error - can assign only exactly <Integer>
//List<? extends Integer> listExtendsInteger_ListNumber = new ArrayList<Number>(); // error - Number is not a subclass of Integer
List<? extends Integer> listExtendsInteger_ListInteger = new ArrayList<Integer>();
//List<? extends Integer> listExtendsInteger_ListDouble = new ArrayList<Double>(); // error - Double is not a subclass of Integer
List<? super Integer> listSuperInteger_ListNumber = new ArrayList<Number>();
List<? super Integer> listSuperInteger_ListInteger = new ArrayList<Integer>();
//List<? super Integer> listSuperInteger_ListDouble = new ArrayList<Double>(); // error - Double is not a superclass of Integer
listNumber_ListNumber.add(3); // ok - allowed to add Integer to exactly List<Number>
// These next 3 are compile errors for the same reason:
// You don't know what kind of List<T> is really
// being referenced - it may not be able to hold an Integer.
// You can't add anything (not Object, Number, Integer,
// nor Double) to List<? extends Number>
//listExtendsNumber_ListNumber.add(3); // error - can't add Integer to *possible* List<Double>, even though it is really List<Number>
//listExtendsNumber_ListInteger.add(3); // error - can't add Integer to *possible* List<Double>, even though it is really List<Integer>
//listExtendsNumber_ListDouble.add(3); // error - can't add Integer to *possible* List<Double>, especially since it is really List<Double>
listSuperNumber_ListNumber.add(3); // ok - allowed to add Integer to List<Number> or List<Object>
listInteger_ListInteger.add(3); // ok - allowed to add Integer to exactly List<Integer> (duh)
// This fails for same reason above - you can't
// guarantee what kind of List the var is really
// pointing to
//listExtendsInteger_ListInteger.add(3); // error - can't add Integer to *possible* List<X> that is only allowed to hold X's
listSuperInteger_ListNumber.add(3); // ok - allowed to add Integer to List<Integer>, List<Number>, or List<Object>
listSuperInteger_ListInteger.add(3); // ok - allowed to add Integer to List<Integer>, List<Number>, or List<Object>
関連
-
[解決済み] android.os.NetworkOnMainThreadException' を修正するにはどうすればよいですか?
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] 整数の平方根が整数であるかどうかを判断する最速の方法
-
[解決済み] Javaで数値を小数点以下n桁に丸める方法
-
[解決済み] Eclipseにプロジェクトをインポートした後に「Must Override a Superclass Method」エラーが発生する。
-
[解決済み] JSP/Servletを使用してサーバーにファイルをアップロードするにはどうすればよいですか?
-
[解決済み] メソッドの戻り値の型を汎用的にするにはどうすればよいですか?
-
[解決済み] C#でジェネリックメソッドからNULLを返すにはどうしたらいいですか?
-
[解決済み] voidメソッドが例外を投げるかどうかをMockitoがテストする
-
[解決済み】TをEnumに拘束するGenericメソッドの作成
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Java Exceptionが発生しました エラー解決
-
java の例外が発生しました java
-
final, finally, finalizeの違いについて話してください。
-
SpringBootApplication を型解決できない。
-
javaの模造品QQ WeChatのチャットルーム
-
eclipse の実行時に java 仮想マシンが見つからなかった
-
javaコンパイル時のエラー:不正な文字 '\ufeff' に対する解決策です。
-
SocketTimeoutExceptionの解決方法です。読み込みがタイムアウトした
-
Exception: java.util.NoSuchElementException: 行が見つかりません
-
maven プラグイン エラー プラグインの実行は、ライフサイクル構成ソリューションの対象外です。