Java 与嵌套泛型集合的混淆
请帮助我了解为什么Java 与嵌套泛型集合的混淆,java,generics,collections,covariance,contravariance,Java,Generics,Collections,Covariance,Contravariance,请帮助我了解为什么add1()和add4()报告错误,以及为什么add2()和add3()不报告错误。具体来说,如果编译器允许编译其中的每一个,请给出不希望出现的后果的示例 class InnerTypeConfusion { interface Animal {} class Dog implements Animal {} class Room<T> { void add(T t) {} } void add1(Room<? ex
add1()
和add4()
报告错误,以及为什么add2()
和add3()
不报告错误。具体来说,如果编译器允许编译其中的每一个,请给出不希望出现的后果的示例
class InnerTypeConfusion {
interface Animal {}
class Dog implements Animal {}
class Room<T> {
void add(T t) {}
}
void add1(Room<? extends Animal> room) {
// Error: The method add(capture#1-of ? extends Animal) in the type
// Room<capture#1-of ? extends Animal> is not applicable for the
// arguments (Dog)
room.add(new Dog());
}
void add2(Room<Animal> room) {
room.add(new Dog());
}
class Cage<T> {}
void add3(Room<Cage<? extends Animal>> room) {
room.add(new Cage<Dog>());
}
void add4(Room<Cage<Animal>> room) {
// The method add(Cage<Animal>) in the type Room<Cage<Animal>> is not
// applicable for the arguments (Cage<Dog>)
room.add(new Cage<Dog>());
}
}
类内部类型混淆{
界面动物{}
类Dog实现动物{}
教室{
void add(T){}
}
无效添加1(房间用于添加1
:
// We don't want to add a Dog to a room of cats...
Room<Cat> cats = new Room<Cat>();
add1(cats);
Cat cat = cats.get(0);
//我们不想在猫的房间里添一只狗。。。
房间猫=新房间();
地址1(猫);
Cat=cats.get(0);
对于add4
,我们不想将Cage
添加到Cage
的房间
。Cage
不是Cage
,尽管在方法void add1中它是Cage(房间当你使用一个未知类型的列表,标记为?
,该列表几乎是只读的。你只能在其中插入null
。你不能使用列表中的项目。这里你处理的是动物的一个未知子类
void add1(List<? extends Animal> list) {
list.add(new Dog());
}
谢谢,所以现在我清楚地明白了为什么add1()
不应该编译,但是现在我不明白为什么add3()
编译正确。谢谢,所以现在我清楚地明白了为什么add1()
不应该编译,但是现在我不明白为什么add3()
编译正确。@glenviewjeff这是错误的,所以我删除了它,用不同的措辞重写了它。@glenviewjeff好的,写了关于这个主题的详细解释。希望这会有帮助。Max我希望你不要介意我大量编辑了你的答案,而不是添加了我自己的答案。非常感谢——通过这个问题,我学到了很多东西!@glenviewjeff没问题,谢谢你的添加,也许有人会发现它和你一样有用:)Adrian,我不确定你在你的add1
版本中添加了对Animal
的强制类型,你想显示什么。你只是在显示隐式强制类型吗?你知道这个版本的add1()
也不会编译,对吗?@glenviewjeff他说的是,如果你的方法参数定义为Cage,我喜欢你解释add1
的只读维度。它是只读的,因为无法确定列表的实际类型。但是,我不明白你在粘贴ad时的意图d4
未修改。你是想更改某些内容以使其编译吗?@glenviewjeff否我本想回复他发布的代码,所以我将代码包括在内。我希望它能让我的回复更清楚,因为你知道我指的是代码的哪一部分。
Room<Cage<? extends Animal>> room = new Room<Cage<? extends Animal>>();
add3(room);
// Here we create a room that can contain only dog cages
Room<Cage<Dog>> room = new Room<Cage<Dog>>();
// But the method needs a "any kind of animal cage" room
// Therefore we get error during compilation
add3(room);
void add(Room<Cage<? super Dog>> room) {
room.add(new Cage<Dog>());
room.add(new Cage<Animal>());
}
void add1(List<? extends Animal> list) {
list.add(new Dog());
}
void add4(List<Cage<Animal>> list) {
list.add(new Cage<Dog>());
}