7

私がこのようなことをしようとしている場合:

List<?> unknownList = new ArrayList<>();

その後、コードは正常にコンパイルおよび実行されますが、どのタイプArrayList作成されたのでしょうか?

そして、この行の後、私がこのようにした場合:

        unknownList.add("str"); //compilation error

コンパイルエラーが発生します:

error: no suitable method found for add(String)
        unList.add("str");
              ^
method List.add(int,CAP#1) is not applicable
  (actual and formal argument lists differ in length)
method List.add(CAP#1) is not applicable
  (actual argument String cannot be converted to CAP#1 by method invocation conversion)
method Collection.add(CAP#1) is not applicable
  (actual argument String cannot be converted to CAP#1 by method invocation conversion)
where CAP#1 is a fresh type-variable:
    CAP#1 extends Object from capture of ?

このエラーは何ですか?ワイルドカードでダイヤモンド演算子を使用するのは適切ですか? はいの場合、どこで???

4

3 に答える 3

4

しかし、ArrayList はどの型で作成されたのでしょうか?

型パラメーターはコンパイル時に適用される単なる制約ですが、型消去は型パラメーターのすべての出現をその消去 (この場合はObject) に置き換えます。したがって、ランタイム タイプについて尋ねている場合、それはプレーンになりますArrayList(これは と考えることができますArrayList<Object>)。

ワイルドカードでダイヤモンド演算子を使用するのは良いですか? はいの場合、どこで???

いいえ。ひし形演算子を使用してジェネリック クラスの新しいオブジェクトを作成する場合、型パラメーターを冗長にしたくないことを意味します。具体的な型パラメーターを持たない、ワイルドカードで宣言された変数と組み合わせてはなりません

要約すると、次のように書くべきではありません。

List<?> unknownList = new ArrayList<>();

<?>タイプが実際に重要でない場合にのみ、ワイルドカードを使用してください。特に、リストにアイテムを追加する場合は、ワイルド カードを使用しないでください。アイテムを追加すると、追加するタイプがわかるからです。

たとえば、値にアクセスせずにリストを渡す場合、またはリスト項目にプレーンなオブジェクトとしてアクセスする場合など、メソッドのパラメーターとして使用される可能性があります。

于 2014-04-08T11:35:31.987 に答える
2

あなたのエラーは、タイプの変数があり、それList<?>を呼び出しaddて、String.

変数がタイプの場合はそれを行うことができますList<String>が、それは type のみであるため、変数が参照するリストにList<?>a を追加することが正当であるかどうかをコンパイラーが知る方法はありません。String

文字列を保存する場合は、それらを保存する型の変数List<String>(またはその他の文字列のコレクション) があることを確認してください。

また、ダイヤモンド演算子を使用して、型にワイルドカードを含む変数に格納されるものを作成しても問題ありません。ひし形演算子は、実行時に得られるものに違いはありません。実行時には、型パラメーターはありません。作成したオブジェクトに対して行う後続の操作は、オブジェクトの作成に使用したコード行ではなく、変数の型に対してコンパイル時にチェックされます。

于 2014-04-08T11:38:36.087 に答える
0

しかし、ArrayList が作成した型はどれでしょうか?

かもしれませんArrayList<Object>。かもしれませんArrayList<String>。かもしれませんArrayList<SomeBogusUnrelatedClass>。とにかくコンパイルされたコードに違いがないため、それは本当に問題ではありませんList<?>

ワイルドカードでダイヤモンド演算子を使用するのは良いですか?

いいえ。新しく作成されたジェネリック オブジェクトへのワイルドカード パラメーター化された参照を持つことは意味がありません。

于 2014-04-08T23:41:25.143 に答える