【问题标题】:Explanation of the get-put principleget-put原理的解释
【发布时间】:2009-08-18 06:22:08
【问题描述】:

我读过 O'Reilly 的书,因为我了解了这个 get-put 原则

  • 当您仅从结构中获取值时,请使用 extends 通配符。
  • 当您只值放入结构时,请使用 super 通配符。
  • 当你们都想从结构中获取和放入结构时,不要使用通配符。

例外情况是:

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

  • 除了 Object 类型的值(超类型)之外,您无法从使用 super 通配符声明的类型中获取任何内容每种引用类型。

谁能帮我深入探索这条规则?如果可能,请把它们分层排列。

【问题讨论】:

  • +1:总是很高兴看到有人寻求对基本面的澄清
  • @Everyone,我认为您是指基础意义上的基础而不是背侧?

标签: java generics


【解决方案1】:

考虑一束香蕉。这是Collection<? extends Fruit>,因为它是一种特定水果的集合——但你不知道(从该声明中)它是哪种水果的集合。您可以从中得到一个物品,并且知道它肯定是水果,但您不能添加到它——您可能正试图将一个苹果添加到一堆中香蕉,这肯定是错误的。您可以在其中添加null,因为这将是任何种水果的有效值。

现在考虑一个果盘。这是一个Collection<? super Banana>,因为它是某种“大于”Banana(例如Collection<Fruit>Collection<TropicalFruit>)的类型的集合。您绝对可以在其中添加一根香蕉,但如果您从碗中取出一个物品,您不知道会得到什么 - 它很可能不是是一根香蕉.您可以确定的是,它将是一个有效的(可能是nullObject 参考。

(一般来说,对于 Java 泛型问题,Java Generics FAQ 是一个极好的资源,其中包含几乎所有与泛型相关的问题的答案。)

【讨论】:

  • 但是在从 Collection 中获取水果时,您可能会得到除香蕉以外的任何水果。同样,在放水果的同时,您可以添加任何可能不属于香蕉果实的东西
  • Java 将阻止您将 null 以外的任何内容添加到 Collection<? extends Fruit> 正是出于这个原因,并且正是出于这些原因,您必须显式转换获取项目的结果。跨度>
  • @JonSkeet 这可能是一个愚蠢的问题,但在什么情况下不能同时“访问” add() 和 get() 方法有用?我的意思是,要从列表中获取()某个对象,您必须先添加它,对吗?反之亦然,如果你以后不能得到它,你为什么要添加它?
  • @Timmos:仅仅因为 something 必须能够添加值并不意味着 all 代码必须能够。例如,为了显示人名列表,我可能只需要一个Collection<? extends Person>(或者更可能只是一个Iterable<? extends Person>,但是......)。 创建该集合的代码很可能需要它是Collection<Employee>,但消费代码不需要。
  • @Timmos:在这种情况下,您必须确切地说您所说的“它”是什么意思......但是是的,Java 泛型的规则旨在提供类型安全。
猜你喜欢
  • 2011-02-04
  • 2020-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-15
  • 2015-01-17
  • 2015-12-29
  • 2023-04-02
相关资源
最近更新 更多