为什么这段带有泛型的java代码不';不编译
Test.java:为什么这段带有泛型的java代码不';不编译,java,generics,compiler-construction,Java,Generics,Compiler Construction,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<Wr
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);
}
}
}
我的问题不是如何让代码正常工作。而是为什么这段代码不能编译。上面的代码以一种非正统的方式使用泛型,并且它还产生编译警告。但是,我仍然希望编译器有足够的信息来编译上述代码。您声明
Wrapper test = stack.pop();
您使用的是包装器
。因此,在编译时,所有具有泛型组件的方法和字段都会以擦除的形式出现
所以
ArrayList
的iterator()
方法声明为
public Iterator<E> iterator() {
E next();
迭代器#next()
方法声明为
public Iterator<E> iterator() {
E next();
因此,它的擦除反过来成为
Object next();
您正在隐式(通过for each循环)尝试将类型为
对象的值分配给类型为包装器的引用
public static void testing (Stack<Wrapper> stack) // <-- Here
公共静态无效测试(堆栈)//
然而,我仍然希望编译器有足够的信息来编译上述代码
不,没有。因为你没有给编译器足够的信息
您正在代码中使用原始类型包装器
,在这种情况下,编译器无法获得所有泛型类型信息。因此,编译器将ArrayList
看作是ArrayList
,这就是为什么当您迭代它时,您将返回对象
类型值,而不是包装器
类型
有关更多详细信息,请参阅:
未从其超类或超接口继承的原始类型C的构造函数(§8.8)、实例方法(§8.4,§9.4)或非静态字段(§8.3)M的类型是对应于在对应于C的泛型声明中删除其类型的原始类型
另请参见:
包装器堆栈中的T在哪里?我想应该是像Stack一样的
Object next();
public static void testing (Stack<Wrapper> stack) // <-- Here
Wrapper test = stack.pop(); // <-- or here.