为什么 java 让我添加一个 Box(原始类型)到 List<Box<? extends Item>>

Why java lets me add a Box(Raw type) to a List<Box<? extends Item>>

此代码有效,我不明白列表如何添加原始类型框,我认为类型擦除会将类型设置为指定的边界。 注意:Paper class 没有扩展 Bakery class.

编辑:我的理解正确吗?编译器对原始框类型进行类型转换,以便将其添加到列表中?这只在编译时有效吗?所以如果我试图在运行时获取值,它会抛出异常吗?

class Violator {

    public static List<Box<? extends Bakery>> defraud() {
        List<Box<? extends Bakery>> list = new ArrayList<>();
        Paper paper = new Paper();
        Box box = new Box<>();
        box.put(paper);
        list.add(box);
        return list;
    }
}
class Box<T> {
    void put(T item) { /* implementation omitted */ }
    T get() { /* implementation omitted */ }
}

此代码确实会生成未经检查的转换警告,关于其允许的原因,来自 Angelika Langer's blog

为什么允许原始类型?

To facilitate interfacing with non-generic (legacy) code. Raw types are permitted in the language predominantly to facilitate interfacing with non-generic (legacy) code.

If, for instance, you have a non-generic legacy method that takes a List as an argument, you can pass a parameterized type such as List<String> to that method. Conversely, if you have a method that returns a List , you can assign the result to a reference variable of type List<String> , provided you know for some reason that the returned list really is a list of strings.

你的答案在于相反,如果你有一个returns一个List的方法,你可以将结果赋给一个类型的引用变量List<String>。在您的情况下,您可能有一个遗留方法 returns a Box

 // Legacy code
 private Box getBox(){
     // returns a Box which satisfy the Box<? extends Bakery>
 }

即使返回的结果可能满足约束 Box<? extends Bakery>,也无法完全确定,因此您可以将该框添加到列表中