Test.java:
import java.util.ArrayList;
import java.util.Stack;
import java.util.Iterator;
class Wrapper<T> {
public T content;
public ArrayList<Wrapper> children;
}
public class Test {
public static void testing (Stack<Wrapper> stack) {
Wrapper test = stack.pop();
Iterator<Wrapper> itr = test.children.iterator();
while (itr.hasNext()) {
Wrapper item = itr.next();
System.out.println(item.content);
}
ArrayList<Wrapper> canCompile = test.children;
for (Wrapper child : canCompile) {
System.out.println(child.content);
}
for (Wrapper child : test.children) {
System.out.println(child.content);
}
}
}
Error:
Test.java:25: error: incompatible types
for (Wrapper child : test.children) {
^
required: Wrapper
found: Object
Note: Test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
My question isn't how to get this code to work. But rather why this code as it stands doesn't compile. The above code uses generics in a way that's unorthodox, and it also yields compilation warnings. However I would still expect the compiler to have enough information to compile the above piece of code.
However I would still expect the compiler to have enough information to compile the above piece of code.
No it doesn't. Because you didn't gave the compiler enough information.
You are using a raw type Wrapper
in your code, in which case, all the generic type information is not available to the compiler. So, the compiler sees ArrayList<Wrapper>
as just ArrayList
, and that is why when you iterate over it, you'll get back Object
type values and not Wrapper
type.
See JLS § 4.8 - Raw Types for more details:
The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) M of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.
Also See: