11

重複の可能性:
インスタンスにジェネリック型が割り当てられていない場合の for each ループの問題のジェネリック

誰かiterate1()がコンパイラ (Java 1.6) によって受け入れられない理由を明確にできますか? 理由はわかりませんがiterate2()iterate3()はるかに優れています。

import java.util.Collection;
import java.util.HashSet;

public class Test<T> {

    public Collection<String> getCollection() {
        return new HashSet<String>();
    }

    public void iterate1(Test test) {
        for (String s : test.getCollection()) {
            // ...
        }
    }

    public void iterate2(Test test) {
        Collection<String> c = test.getCollection();
        for (String s : c) {
            // ...
        }
    }

    public void iterate3(Test<?> test) {
        for (String s : test.getCollection()) {
            // ...
        }
    }


}

コンパイラ出力:

$ javac Test.java
Test.java:11: incompatible types
found   : java.lang.Object
required: java.lang.String
  for (String s : test.getCollection()) {
                                              ^
Note: Test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
4

1 に答える 1

14

生の型を使用する場合 (たとえば、TestではなくTest<T>、コンパイラはそれ ( JLS 4.8 )をその型 ( JLS 4.6 ) の消去として扱います。つまり、型パラメーターを使用するかどうかにかかわらず、ジェネリックを完全に消去します。

コンストラクターまたはメソッドの型パラメーター (§8.4.4)、およびメソッドの戻り値の型 (§8.4.5) も、コンストラクターまたはメソッドの署名が消去されると消去されます。

基本的に、生の型の使用は、そのコードがジェネリックをまったく認識しないようにすることを示すものとしてコンパイラによって処理されます。そのため、メソッド シグネチャは次のように消去されます。

public Collection getCollection()

...したがって、JLS 14.14.2 に従ってObject、推論された要素タイプが であるため、コンパイル時エラーが発生します。

于 2012-10-02T15:47:36.747 に答える