我正在努力解决这个问题,并且想知道是否有人可以解释原因.
我有三个班:员工,人和天使.
员工延伸人和人延伸天使.
当我尝试执行此代码时
class Angel {}
class Person extends Angel {}
class Employee extends Person {}
Run Code Online (Sandbox Code Playgroud)
我收到一个错误:
在类型List中添加(捕获#5-of?super Person)的方法不适用于参数(Angel)
我一直在阅读文档<? super X >意味着任何类型的X或X的超类(所以在我的情况下,Angel是Person的超类)并且应该被允许?显然不是!
有没有人有任何简单的例子?
Mar*_*nik 21
你的直觉逻辑说"a List<? super Person>是一个属于Person或超类型的事物Person的列表,所以我自然可以添加Angel到其中".这种解释是错误的.
声明List<? super Person> list保证list将是允许将任何内容Person添加到列表中的类型.由于Angel 不是aPerson,编译器自然不允许这样做.考虑使用调用方法insertElements(new ArrayList<Person>).可以添加Angel到这样的列表中吗?当然不.
推理它的最好方法List<? super Person>是没有明确的类型:它是描述允许作为参数的一系列类型的模式.看看List<Person>它不是一个子类型List<? super Person>,而是一个匹配这个模式的类型.允许的操作List<? super Person>是任何匹配类型允许的操作.
Fra*_*raK 11
对我来说,这些答案都不够清楚,尽管他们帮助了我.看了很多,我的意思很多,我终于想出了最简单的通配符解释:
public class CatTest {
public class Animal {}
public class Cat extends Animal {}
public class MyCat extends Cat {}
public class Dog extends Animal {}
public static void main(String[] args) {
List<Animal> animalList = new ArrayList<>();
List<Cat> catList = new ArrayList<>();
List<MyCat> myCatList = new ArrayList<>();
List<Dog> dogList = new ArrayList<>();
CatTest catTest = new CatTest();
// Here you are trying to add a MyCat instance (in the addMethod we create a MyCat instance). MyCat is a Cat, Cat is an Animal, therefore MyCat is an Animal.
// So you can add a new MyCat() to a list of List<Animal> because it's a list of Animals and MyCat IS an Animal.
catTest.addMethod(animalList);
// Here you are trying to add a MyCat instance (in the addMethod we create a MyCat instance). MyCat is a Cat.
// So you can add a new MyCat() to a list of List<Cat> because it is a list of Cats, and MyCat IS a Cat
catTest.addMethod(catList);
// Here you are trying to add a MyCat instance (in the addMethod we create a MyCat instance). MyCat is a Cat.
// Everything should work but the problem here is that you restricted (bounded) the type of the lists to be passed to the method to be of
// a type that is either "Cat" or a supertype of "Cat". While "MyCat" IS a "Cat". It IS NOT a supertype of "Cat". Therefore you cannot use the method
catTest.addMethod(myCatList); // Doesn't compile
// Here you are adding a MyCat instance (in the addMethod we create a MyCat instance). MyCat is a Cat.
// You cannot call the method here, because "Dog" is not a "Cat" or a supertype of "Cat"
catTest.addMethod(dogList); // Doesn't compile
}
public void addMethod(List<? super Cat> catList) {
// Adding MyCat works since MyCat is a subtype of whatever type of elements catList contains
// (for example Cat, Animal, or Object)
catList.add(new MyCat());
System.out.println("Cat added");
}
}
Run Code Online (Sandbox Code Playgroud)
最后,这些是结论:
当使用通配符的工作,通配符应用到列表的类型作为参数传递给方法,不要类型的的元素,当您尝试将元素添加到列表中.在该示例中,您收到以下编译错误:
CatTest类型中的方法addMethod(List)不适用于参数(List)
如您所见,错误是关于方法签名,而不是关于方法的主体.因此,您只能传递 "Cat"元素列表或"Cat"(List<Animal>, List<Cat>)的超类型元素列表.
一旦你通过一个列表与特定类型的元素,你可以只添加元素,是不是"猫"和"猫"的子类型列表中,也就是说,它的行为一如既往,当你有元素的集合!您无法将" Animal " 添加到" Cat " 列表中.正如我之前所说,通配符不适用于元素本身,这些限制仅适用于"列表".现在,为什么呢?由于简单,明显,众所周知的原因:
Animal animal = new Dog();
Run Code Online (Sandbox Code Playgroud)
如果您可以将 "Animal" 添加到"Cat"列表中,您还可以添加"Dog"("Dog"是"Animal"),但它不是"Cat".
| 归档时间: |
|
| 查看次数: |
4946 次 |
| 最近记录: |