为什么这段带有泛型的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

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);
        }
    }
} 
我的问题不是如何让代码正常工作。而是为什么这段代码不能编译。上面的代码以一种非正统的方式使用泛型,并且它还产生编译警告。但是,我仍然希望编译器有足够的信息来编译上述代码。

您声明

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.