Iterating over member typed collection fails when using untyped reference to generic object

generics, java

Solution

When you use a raw type (e.g. `Test` rather than `Test<T>`, the compiler treats it (JLS 4.8) as the erasure of that type (JLS 4.6) - that erases generics completely, whether they use the type parameter or not:

The type parameters of a constructor or method (§8.4.4), and the return type (§8.4.5) of a method, also undergo erasure if the constructor or method's signature is erased.

Basically, the use of a raw type is treated by the compiler as an indication that you don't want that code to be aware of generics at all - so the method signature is erased to:

public Collection getCollection()

... hence the compile-time error, as the inferred element type is `Object`, as per JLS 14.14.2.

Problem

Possible Duplicate: Generics in for each loop problem if instance does not have generic type assigned Could someone clarify why `iterate1()` is not accepted by compiler (Java 1.6)? I do not see why `iterate2()` and `iterate3()` are much better. ``` 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()) { // ... } } } ``` Compiler output: ``` $ 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 ```

Original source

Related problems