Evo*_*lor 11 java syntax extends
在尝试理解Spring MVC中的概念之后,我遇到了Collection<? extends Book>我以前从未见过的表达式.我试图自己搞清楚,但我发现使用Collection<? extends Book>和没有区别Collection<Book>.我猜它只允许Book的扩展,但它确实允许Book.抓那个.我曾尝试使用谷歌,但从那以后?是google中的通配符,它几乎不可能搜索.我已经搜索了stackoverflow以获得答案,但所有关于此问题的问题(例如List <?extends MyType>和<?extends> Java语法)已经知道了Collection<? extends T>.这段代码最初引起了我的兴趣:
import java.util.ArrayList;
import java.util.Collection;
public class Book {
public static void main(String[] args) {
BookCase bookCase1 = new BookCase();
BookCase bookCase2 = new BookCase(bookCase1);
}
}
class BookCase extends ArrayList<Book> {
public BookCase() {
}
//acts same as public BookCase(Collection<Book> c) {
public BookCase(Collection<? extends Book> c) {
super(c);
}
}
Run Code Online (Sandbox Code Playgroud)
怎么<? extends T>办?它有什么不同<T>?
编辑:
后续问题:是否BookCase extends ArrayList<Book>意味着BookCase延伸Book?
考虑以下
class Animal { }
class Horse extends Animal { }
private static void specific(List<Animal> param) { }
private static void wildcard(List<? extends Animal> param) { }
Run Code Online (Sandbox Code Playgroud)
如果没有extends语法,则只能使用签名中的确切类
specific(new ArrayList<Horse>()); // <== compiler error
Run Code Online (Sandbox Code Playgroud)
使用通配符扩展,您可以允许Animal的任何子类
wildcard(new ArrayList<Horse>()); // <== OK
Run Code Online (Sandbox Code Playgroud)
使用它通常更好吗?扩展语法,因为它使您的代码更具可重用性和面向未来.
从文档中查看这一点。
一般来说,如果 Foo 是 Bar 的子类型(子类或子接口),而 G 是某种泛型类型声明,则 G 不是 G 的子类型。这可能是您需要了解的泛型最难的事情,因为它违背了我们根深蒂固的直觉。
所以基本上当你写的时候你void doStuff(List<Book>){}只能对一个Book对象列表做一些事情。
不是 Novels,不是 Magazines,不是 ComicBooks。
同样,这是因为虽然Novelextends Book,G<Novel> 实际上并没有扩展 G<Book>。它不是很直观,但文档中的示例将帮助您看到它。
双方Collection<Book>和Collection<? extends Book>代表的集合,可容纳Book实例,可以被认为是一个对象Book通过is-a的关系。此属性也扩展到接口。
此处的区别在于后一种形式被认为是有界的。根据界限,您将无法在此集合中添加或删除元素。
? extends T是一个上界通配符。实际上,它描述了某个类型(?)在低端和高端之间的层次结构界限Book。它具有包容性,因此您可以Book在其中存储实例,但是如果您还有其他类和接口,例如:
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 {}
Run Code Online (Sandbox Code Playgroud)
...您可以在中找到任何这些实例Collection<? extends Book>。
记得我提到您可能无法在此收藏夹中添加或删除东西吗?请记住以下约定:
生产者扩展;消费超级。
请注意,这是从集合的角度来看的。如果集合与绑定extends,则为生产者;如果与绑定,则为super消费者。
也就是说,从该收藏夹的角度来看,它已经产生了所有记录,因此您不能在其中添加新记录。
List<? extends Book> books = new ArrayList<>(); // permanently empty
books.add(new Book()); // illegal
Run Code Online (Sandbox Code Playgroud)
如果是这种情况? super Book,您将无法以理智的方式从中检索元素-您必须改为检索它们Object,这并不简洁。
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
Run Code Online (Sandbox Code Playgroud)
首先,如果您受束缚? super T,则只打算将元素插入该集合中。
后续问题:
BookCase extends ArrayList<Book>是BookCase extends Book吗?
编号A BookCase在该实例的ArrayList,而不是一个Book。数组列表绑定到存储书的情况恰好如此,但它本身不是一个Book。
| 归档时间: |
|
| 查看次数: |
9738 次 |
| 最近记录: |