4

変数を次のように宣言するときにコンパイラが警告を発行するのはなぜですか

 List<? extends Object> list = new LinkedList();

警告:

Note: ZiggyTest.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

しかし、変数を次のように宣言しても警告は発行されません。

List<?> list = new LinkedList();
4

2 に答える 2

2

これは、Java 5以降で、型指定子のないコレクションを使用している場合に発生します(たとえば、のArraylist()代わりにArrayList<String>())。これは、ジェネリックスを使用して、タイプセーフな方法でコレクションを使用していることをコンパイラーがチェックできないことを意味します。

警告を取り除くには、コレクションに保存しているオブジェクトの種類を具体的に指定してください。だから、代わりに

List list = new ArrayList();

次のようになります

List<String> list = new ArrayList<String>();

あなたの場合、そのステートメントを次のように変更すると、

List<? extends Object> list = new LinkedList<Object>();

ジェネリック型()を使用して型セーフになっているため、警告なしでコンパイルされます<Object>

于 2012-01-01T21:48:40.990 に答える
1

コンパイラがこれらを同等として扱わない理由を説明することはできませんが、そうでないことを考慮して、なぜそうすることを拒否するのかを説明しようと思います。

最初の(List<? extends Object>)は、に保持されているオブジェクトのタイプが、Listから派生した未知のタイプであることを示していObjectます。2番目の(List<?>)は少ないと言っています。リスト内のオブジェクトのタイプが不明であると言っているだけです。未知のタイプの上限として、予想されるスーパータイプについては言及されていません。

List最初の仮定を検証するために、コンパイラーは、ここでraw型として構築されたインスタンスに保持されている予想される型について何かを言うのを聞きたいと思っていますLinkedList。ただし、インスタンスをタイプとして構築する場合LinkedList<Object>は、少なくとも、インスタンスに対する共変読み取りがアサーションと一致することを保証します。つまり、このリストにあるものはある種のものですObject

さて、これはすべてばかげているように見えます。Javaのすべての参照/非プリミティブ型が拡張されるため、との間でObject解釈に違いはないはずです。結局のところ、2番目のものは、言語の型システムの義務付けられた単一ルートのクラス階層のおかげで、最初のものを意味します。List<? extends Object>List<?>

于 2012-01-01T22:31:05.147 に答える