28

生のリストは問題なく変換されList<?>ます。生のリストのリストを のリストに変換できないのはなぜList<?>ですか?

{   // works
    List raw = null;
    List<?> wild = raw;
}
{   // Type mismatch: cannot convert from List<List> to List<List<?>>
    List<List> raw = null;
    List<List<?>> wild = raw;
}

バックストーリー( xy問題を軽減するため):

私が使用している API は return を返しますList<JAXBElement>。私はそれが常にであることをたまたま知っていますList<JAXBElement<String>>。ループして独自の をビルドする予定List<String>ですが、 を書くときに未加工の型コンパイラの警告を修正しようとしました (抑制はしません) List<JAXBElement> raw = api();

私は試した:

List<JAXBElement<?>> raw = api();
List<JAXBElement<?>> raw = (List<JAXBElement<?>>) api();

しかし、これらはタイプの不一致エラーを引き起こします。

興味深いことに、これは警告もエラーも発生しません。

for (JAXBElement<?> e : api()) {
    // ...
}
4

3 に答える 3

3

生の型List は と同じではないため、直接割り当てたりキャストしたりすることはできませんList<?>

型チェックを使用Listする場合は無視され、任意の型で任意のジェネリック メソッドを使用できます。コンパイラを使用する場合List<?>ジェネリック パラメータを持つメソッドを使用できません


したがって、警告を無視することもできます:

@SuppressWarnings("rawtypes")

および/または回避策を使用して明示的にキャストします。

List<JAXBElement<String>> raw = (List<JAXBElement<String>>) ((Object)api());
于 2014-11-05T20:52:18.980 に答える
0

警告のみを削除したい場合は、@SuppressWarnings("rawtypes") を使用できます。

基本的に問題は、コンパイラがrawtypeを以前のジェネリックのプリミティブオブジェクトとして扱うため、「古いオブジェクト」は「ジェネリックオブジェクト」ではないため、キャストできないことです。

公式ドキュメントからこれを読んでください: http://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html

ただし、生の型をパラメーター化された型に割り当てると、次の警告が表示されます。

Box rawBox = new Box(); // rawBox は Box の raw タイプです Box intBox = rawBox; // 警告: unchecked conversion 未加工の型を使用して、対応するジェネリック型で定義されたジェネリック メソッドを呼び出す場合にも、警告が表示されます。

Box stringBox = new Box<>(); ボックス rawBox = stringBox; rawBox.set(8); // 警告: set(T) への未チェックの呼び出し 警告は、raw 型がジェネリック型チェックをバイパスし、安全でないコードのキャッチをランタイムに延期することを示しています。したがって、生の型の使用は避ける必要があります。

于 2014-11-05T20:50:20.080 に答える