10

以下がコンパイルされないのはなぜですか?コンパイラは+、印刷行のサインに対してエラーを出します。

public class Test<T> {
  HashMap<Integer,Integer> m = new HashMap<Integer, Integer>();
  public static void main(String[] args) {
    Integer zero1 = 0;
    Integer zero2 = 0;
    Test t = new Test();
    t.m.put(1,zero1);
    t.m.put(2,zero2);
    System.out.println(t.m.get(1)+t.m.get(2)==t.m.get(2));
  }
}

型消去は理解できますが、mはaHashMap<Integer,Integer>であり、型にまったく依存しないはず<T>です。コンパイラがこれを拒否するのはなぜですか?最初の行で削除<T>するとコンパイルできますが、なぜこれがうまく機能しないのかわかりません。

これはコンパイラのバグですか、それともそのような動作の背後にあるロジックはありますか?

4

2 に答える 2

8

理由はわかりませんが、動作は定義上正しいようです。Java言語仕様の§4.8「生の型」は、次のように明示的に述べています。

スーパークラスまたはスーパーインターフェースから継承されていない生の型 Cのコンストラクタ ( §8.8 )、インスタンス メソッド ( §8.4§9.4 )、または非静的フィールド ( §8.3 )Mの型は、対応する生の型です。 C に対応するジェネリック宣言での型の消去。

あなたの例では、生の型 C は(またはその他Testとは対照的に) であり、非静的フィールドはです。上記の規則の結果として、 の型は ではなく生の型であり、したがって の戻り値の型はではなく です。Test<Object>Test<Integer>Mmt.mHashMapHashMap<Integer, Integer>t.m.get(Object)ObjectInteger

于 2012-09-27T02:09:51.380 に答える
1

行を置き換えるだけです:

Test t = new Test();

に:

Test<Integer> t = new Test<Integer>();

そしてそれはうまくいくでしょう。

于 2012-09-27T01:59:40.403 に答える