获取原则的解释

Jav*_*esp 77 java generics

我读过O'Reilly的书,因为我开始了解这个获取原则.

  • extends仅从结构中获取值时使用通配符.
  • super仅在值放入结构时使用通配符.
  • 当你们想要从一个结构中获取和放置时,不要使用通配符.

例外情况是:

  • extends除了null属于每个引用类型的值之外,您不能将任何内容放入使用通配符声明的类型中.

  • super除了type的值之外,您不能从使用通配符声明的类型中获取任何内容Object,这是每种引用类型的超类型.

任何人都可以帮助我深入探索这条规则吗?如果可能的话,请将它们分层.

Jon*_*eet 153

考虑一堆香蕉.这是Collection<? extends Fruit>因为它是一个特定的一种水果的集合-但你不知道(从该声明)什么样的水果是集合.你可以从它得到一个项目,并知道它肯定会是一个水果,但你不能添加它 - 你可能会尝试添加一个苹果到一堆香蕉,这肯定是错误的.您可以添加null它,因为这将是任何类型的水果的有效值.

现在考虑一个水果碗.这是一个Collection<? super Banana>,因为它是"大于"某种类型的集合Banana(例如,Collection<Fruit>Collection<TropicalFruit>).你绝对可以添加一个香蕉,但如果你从碗里拿一个东西你不知道你会得到什么 - 它可能不是香蕉.所有你肯定知道它将是一个有效的(可能null)Object参考.

(一般来说,对于Java泛型问题,Java泛型常见问题解答是一个很好的资源,其中包含几乎所有与泛型有关的答案,你可能会把它抛出来.)

  • Java会阻止你向`Collection <?添加除null之外的任何东西.正是出于这个原因扩展了Fruit>`,并且你必须明确地转换获取项目的结果,正是出于这些原因. (6认同)
  • @Timmos:只是因为*某些东西*必须能够添加一个值并不意味着*all*代码需要能够.例如,为了显示人名列表,我可能只需要一个`Collection <?扩展Person>`(或者更可能只是一个`Iterable <?extends Person>`,但是......).代码*创建*该集合可能需要它是一个`Collection <Employee>`,但*consume*代码却不需要. (6认同)
  • @Timmos:在这种情况下,你必须说'确切*'你的意思是什么......但是,是的,Java泛型的规则旨在提供类型安全. (5认同)