2016-01-30 4 views
5
List<? extends String> list = new Arraylist<String>(); 
list.add("foo"); 

与えられたコードによってコンパイル時のエラーが発生します.iなぜリストに文字列を追加できないのですか? が、コードは、我々はStringクラスのオブジェクトを追加することができますし、それはあなたが項目のデータ型に関係ないときリストでワイルドカードを使用中にコンパイル時エラーが発生しました

+1

'String'は** final **クラスなので、実際には意味がありません! 'String'を拡張できるクラスはありません。だから、あなたがすべきことは 'List 'と定義することだけです。 – bobbel

+0

しかし、オブジェクトとしてのStringを持つArrayListの参照はどのように取っていますか? –

+0

'List 'は 'List <? extends String> '違いは* StringはString *ですが、Stringはaではないかもしれませんか?それはString *です。 – Linus

答えて

2

List<?>にのみ使用されるべき理由 はまだ私はエラーを取得していますリスト内のクラスオブジェクトを派生していることを意味しそして、例えば等

のリストのサイズを取得するなどの操作に興味を持って、

public int getSize(List<?> itemList) { 
    return itemList.size(); 
} 

Read Onlyリストの複数です。

Stringの新しいリストを作成する場合は、次の項目を使用する必要があります。また

List<String> list = new Arraylist<>(); 
list.add("foo"); 

、あなたはこれを使用することができます。

List<Object> list = new Arraylist<>(); 
list.add("foo"); 
1

これは動作します:

List<? super String> list = new ArrayList<String>(); 
list.add("foo"); 

は、その後、あなたのコンパイラは、今、呼び出し側であることをしているオブジェクトのリストを渡すことになりますStringまたはスーパータイプ。

<? extends String>と言う場合、それはStringを拡張する任意のタイプであることを意味します。つまり、誰かがListを渡すことができ、それを受け入れることになります。

もここを見て: Difference for <? super/extends String> in method and variable declaration

1

基本的にList<? extends String>知られているすべては、このタイプがStringを拡張することで、未知のタイプの一覧です。変数にList<String>のインスタンスが含まれていても問題ありません。

Aサブクラス Bといくつかのクラスである
List<? extends A> list = new ArrayList<A>(); 

:それでは、考えてみましょう...

は今、文字列は、最終的なので、何のサブクラスではありません。使用される場合、タイプList<? extends A>の変数はList<B>のインスタンスになる可能性があります。 ABではない可能性があるため、Aを追加することはできません。

でも、それは正しいでしょうか? まあ、コンパイラはではなく、一般的に実行時にその変数を変更する可能性があるため、未知の型とインスタンス化したものの間の論理的な接続も予期しません。

同様の例では、方法は(Set<T>, T)を受け入れ、不正通話がSet<?>変数は、Set<String>のインスタンスが含まれているものの(Set<?>, String)を用いpreposedさ楽観More Fun with Wildcards名前チュートリアルで存在します。 extendsが追加されていても、問題は同じです。

関連する問題