2

最初の行は機能するが、2番目の行は機能しないのはなぜですか。

Class<? extends Class> c1                  = (new Object()).getClass().getClass();
Class<? extends Class<? extends Class>> c2 = (new Object()).getClass().getClass().getClass();
4

3 に答える 3

2

のAPIドキュメントからObject.getClass

実際の結果タイプはClasswhere|X|です。getClassが呼び出される式の静的型の消去です。

したがって(new Object()).getClass()、を返しますClass<? extends Object>。それを呼びかけますgetClass。したがって、XはになりますClass。これにより、が得られClass<? extends Class>ます。

于 2012-11-17T10:30:36.020 に答える
0
Type mismatch: cannot convert from Class<capture#5-of ? extends Class> to 
Class<? extends Class<? extends Class>>

それが理由です。ここで生のタイピングが壊れているように見えます。ジェネリックスは、コンパイル中にそのタイプが削除されます。必要な型キャストを追加すると、再び機能します

Class<? extends Class<? extends Class>> c2 = 
(Class<? extends Class<? extends Class>>) (newObject()).getClass().getClass().getClass();
于 2012-11-17T09:10:25.820 に答える
0

Javaは型消去を使用します。そのようなものはありません

Class<? extends Class<? extends Class>>

実際には、しかありませんClass<?>。他のすべては仮想です。

これで、3つのジェネリックExample<G1, G2, G3>を持つクラスのオブジェクトは、実行時に型であることが保証されるだけですExample<?,?,?>。ジェネリックは実行時に消去され、それgetClass()が評価されることを忘れないでください。

ArrayList<Integer> inta = new ArrayList<Integer>();
ArrayList<Double> doua = new ArrayList<Double>();
System.err.println(inta.getClass() == doua.getClass());

を返す必要がありtrueます。したがって、getClass()も同じタイプである必要がありますClass<ArrayList<?>>。外側のタイプは既知であり、実行時に使用できます。ジェネリックは消去されました。

プログラミングエラーを回避するために、次のタイプをキャストできます。

Class<ArrayList<Double>> dacls = (Class<ArrayList<Double>>) doua.getClass();

ただし、それでも整数配列リストと同じクラスになります。

于 2012-11-17T10:37:57.797 に答える