用于 ‘? 延伸’和’? super’in Collection generics

谁能解释我们使用的原因?Collectiongenerics。

例如:

  List numberlist; List numberlist; 

通配符引入了如何使用集合的限制。

例如,使用List List ,我无法在列表中添加新元素。 这是因为我所知道的是列表是Number某种子类型,但我不知道实际的子类型是什么(所以我怎么知道要添加什么?)。 例如,请使用以下代码:

 public void doSomethingWith(List numbers) { numbers.add(Integer.valueOf(0)); // Won't compile } 

这将无法编译,因为这两个方法调用都是合法的:

 doSomethingWith(new ArrayList()); doSomethingWith(new ArrayList()); 

可以做的是从列表中读取元素:

 // This will all compile public void doSomethingWith(List numbers) { for (Number number : numbers) { // Do something with number } // OR Number number = numbers.get(0); // OR Number number = numbers.remove(0); } 

调用get类的方法会返回某种Number ,我们知道因为这个事实? extends Number ? extends Number ,所以我们可以像阅读一样对待它。

另一方面, List List具有完全相反的结果。 我不能再从列表中读取,但我可以写信给它。 我知道? 是的,它绝对是一个Integer的超类,所以列表的具体类型肯定会接受Integer值。 例如:

 public void doSomethingWith(List integers) { integers.add(Integer.valueOf(0)); } 

该代码完全合法。 但是,如果要从列表中读取,唯一的方法是使用Object因为其他任何需要转换(这需要知道其具体类型):

 for (Object obj : integers) // OR Object obj = integers.get(0); // OR Object obj = integers.remove(0); 

什么是真正发生的

这是实际发生的事情。 当你指定? extends Number ? extends Number ,你正在制作任何元素作为参数不可用的方法。 实际上,如果您尝试使用List上的Ctrl + Space在Eclipse中自动完成代码List List ,它在add方法等中显示null作为参数的类型。 同时,所有返回元素的方法都保证至少返回某种Number ,尽管你不会确切地知道它实际上是哪个Number子类。

当你指定? super Integer ? super Integer ,你正在制作任何元素作为参数的方法,保证它们接受Integer值(以及Integer子类)。 这允许你调用像add这样的方法,因为你知道它们会接受Integer类型。 同时,所有返回元素的方法只保证返回一些东西 ,但我们不知道是什么,所以返回元素的所有方法都只能保证返回Object

PECS是一个很好的首字母缩略词,它记住了这一点,它意味着“ P roducer E xtends, C onsumer S upers”。 这意味着如果你想让你的列表给你一些东西,它就是一个制作人,你应该使用extends 。 如果你希望你的列表接受你的东西,它是一个消费者,所以你使用super 。 请参阅此答案了解更多信息

但是,如果我有一个没有边界的通配符怎么办?

它做到了! 限制您调用将generics类型作为参数的方法,并使返回generics类型的所有方法返回Object 。 这是因为我们不知道这种类型是什么。 例如,所有这些分配到List都是合法的:

 List list; list = new ArrayList(); list = new ArrayList(); list = new ArrayList(); 

等等。

它是一个通配符。 ? 表示从数字inheritance或者是Integer类的超类的任何类都可以工作。 希望这可以帮助。 🙂

当你学习通配符和扩展超级之间的差异时,只需记住PECS 。 这条规则的所有内容都非常简单易记。

? 用于在使用generics时定义通配符 。

您在示例中的语句告诉List接受任何Number类型的对象

? 意思是任何一类

 ? extends MyClass 

表示MyClass或MyClass本身的任何子类。

这就是我要说的:

 List numberlist; //Any class that is extended from Number class, for example Integer, BigInt, ... may come List numberlist; //Any class that Integer class is extended from. Here for example Number may come 

因为:

 Integer extends Number{ } 

List ListList都允许添加例如Integers,但是:使用List你可以放入Integers和其他任何“is”数字。 用List List你只能在其中放入一个具体的运行时类型。 它是整数,那么你不能添加另一个也是数字的类型。