Java 收藏<;?扩展T>;vs收集<;T>;
在尝试理解上的概念之后,我遇到了表达式Java 收藏<;?扩展T>;vs收集<;T>;,java,syntax,extends,Java,Syntax,Extends,在尝试理解上的概念之后,我遇到了表达式Collection,下面的示例清楚地显示了Collection从文档中检出之间的区别 一般来说,如果Foo是Bar的一个子类型(子类或子接口),而G是某种泛型类型声明,那么G不是G的一个子类型。这可能是您需要了解泛型的最困难的事情,因为它违背了我们根深蒂固的直觉 也来看看这个 因此,基本上,当您编写voiddostuff(List){}时,您只能对Book对象列表执行操作 非小说s,非杂志s,非漫画书s 同样,这是因为尽管Novel扩展了Book,G实际上
Collection,下面的示例清楚地显示了Collection从文档中检出之间的区别
一般来说,如果Foo是Bar的一个子类型(子类或子接口),而G是某种泛型类型声明,那么G不是G的一个子类型。这可能是您需要了解泛型的最困难的事情,因为它违背了我们根深蒂固的直觉
也来看看这个
因此,基本上,当您编写voiddostuff(List){}
时,您只能对Book
对象列表执行操作
非小说
s,非杂志
s,非漫画书
s
同样,这是因为尽管Novel
扩展了Book
,G
实际上并没有扩展G
。这不是很直观,但文档中的示例将帮助您了解它。考虑以下几点
class Animal { }
class Horse extends Animal { }
private static void specific(List<Animal> param) { }
private static void wildcard(List<? extends Animal> param) { }
类动物{}
马类动物{}
专用静态void特定(列表参数){}
private static void wildcard(List既是Collection
又是CollectionList
是一个可以包含任何书籍的列表。由于对书籍的种类没有限制,您可以向其中添加任何书籍
ListACollection
是一个CollectionTimes,像这样我希望我能绿色勾选多个答案。特别是Makoto和Adam的答案。虽然所有的答案都很有用,但它们特别帮助我理解它。所以如果你想找到这个问题的答案,我建议你在最短的时间内阅读这两个答案ast,包括注释。谢谢大家!!但是马是动物,specific()接受动物列表…那么为什么不接受马列表呢?泛型与标准方法签名的工作方式不同,是foo(动物)可以接受任何类型的动物。@Evorlor,因为如果将类型参数指定为某个对象,编译器希望它是精确的object@Evorlor也许link会有所帮助?是的,这是正确的。Collection
就是不能代表Collection
,不管类型变量出现在哪里,所以它违反了Liskov替代原则。Collection
有一个方法add(Horse)
,而Collection
有add(Animal)
。显然,调用add(Animal)
任何可能的动物
都不能通过静态类型检查器。因此它使用与子对象相同的is-a关系,因此您可以将子对象存储在T
中。在我的示例中,您可以将漫画
的一个实例放在集合
中。让我在这里进行一些调整。这里有一个有点混乱。所以…收集可以满足收集的要求非常感谢您的帮助!我希望我可以绿色检查多个答案,但我不能。知道您的答案(以及Adam的)这对我的理解至关重要,所以谢谢你!我在对这个问题的评论中也向你大喊了一声……但是一种将一些诗歌添加到书籍列表中的方法:addSomePoetry(list
public class Test {
public static void main(String[] args) {
BookCase bookCase1 = new BookCase();
BookCase bookCase2 = new BookCase(bookCase1);
List<FictionBook> fictionBooks = new ArrayList<>();
BookCase bookCase3 = new BookCase(fictionBooks);
}
}
class Book {}
class FictionBook extends Book {}
class BookCase extends ArrayList<Book> {
public BookCase() {
}
//does not act same as public BookCase(Collection<Book> c) {
public BookCase(Collection<? extends Book> c) {
super(c);
}
}
class Animal { }
class Horse extends Animal { }
private static void specific(List<Animal> param) { }
private static void wildcard(List<? extends Animal> param) { }
specific(new ArrayList<Horse>()); // <== compiler error
wildcard(new ArrayList<Horse>()); // <== OK
class Novella extends Book {}
class Magazine extends Book {}
class ComicBook extends Book{}
class Manga extends Magazine {}
class Dictionary extends Book {}
class ForeignLanguageDictionary<T extends Language> extends Dictionary {}
interface Language {}
List<? extends Book> books = new ArrayList<>(); // permanently empty
books.add(new Book()); // illegal
List<? super Book> books = new ArrayList<>();
books.add(new Book());
books.add(new Manga());
Book book = books.get(0); // can't guarantee what Book I get back
Book getBookWithMostPages(List<? extends Book>) {
...
}
Book getBookWithMostPages(Iterable<? extends Book>) {
...
}