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);
}
}
}
错误:
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
我的问题不是如何让这段代码工作。但是为什么这个代码不能编译。上面的代码以非正统的方式使用泛型,并且它还产生编译警告。但是我仍然期望编译器有足够的信息来编译上面的代码。
答案 0 :(得分:1)
你宣布了
Wrapper test = stack.pop();
您使用Wrapper
作为raw type。因此,在编译时,所有具有通用组件的方法和字段都显示为其擦除。
所以
public ArrayList<Wrapper> children;
显示为
public ArrayList children;
iterator()
的{{1}}方法声明为
ArrayList
其中public Iterator<E> iterator() {
是E
的类型参数。它的删除变得
ArrayList
public Iterator iterator() {
方法声明为
Iterator#next()
所以它的擦除反过来变成
E next();
您隐式(通过for-each循环)尝试将类型Object next();
的值分配给类型为Object
的引用。
答案 1 :(得分:1)
您没有输入Wrapper
,
public static void testing (Stack<Wrapper> stack) // <-- Here
或
Wrapper test = stack.pop(); // <-- or here.
而且,这就是为什么这不是通用的。您应该Wrapper<TYPE>
TYPE
是合适的。
答案 2 :(得分:0)
但是我仍然期望编译器有足够的信息来编译上面的代码。
不,不。因为你没有给编译器足够的信息。
您在代码中使用原始类型Wrapper
,在这种情况下,编译器无法使用所有泛型类型信息。因此,编译器将ArrayList<Wrapper>
视为ArrayList
,这就是为什么当您迭代它时,您将返回Object
类型值,而不是Wrapper
类型。< / p>
有关详细信息,请参阅JLS § 4.8 - Raw Types:
未从其超类或超接口继承的原始类型C的构造函数(第8.8节),实例方法(第8.4节,第9.4节)或非静态字段(第8.3节)M的类型是原始的在与C对应的泛型声明中对应于其类型擦除的类型。
另见: