为什么 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>
,也无法完全确定,因此您可以将该框添加到列表中
此代码有效,我不明白列表如何添加原始类型框,我认为类型擦除会将类型设置为指定的边界。 注意: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 asList<String>
to that method. Conversely, if you have a method that returns aList
, you can assign the result to a reference variable of typeList<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>
,也无法完全确定,因此您可以将该框添加到列表中