当前位置: 首页 > news >正文

建设网站视频素材洮南做网站

建设网站视频素材,洮南做网站,宁波网站改版,营销软件网站建设&#xff1f; extends T ? extends T 描述了通配符上界, 即具体的泛型参数需要满足条件: 泛型参数必须是 T 类型或它的子类, 例如: List<? extends Number> numberArray new ArrayList<Number>(); // Number 是 Number 类型的 List<? extends Number>…

? extends T

? extends T 描述了通配符上界, 即具体的泛型参数需要满足条件: 泛型参数必须是 T 类型或它的子类, 例如:

List<? extends Number> numberArray = new ArrayList<Number>();  // Number 是 Number 类型的
List<? extends Number> numberArray = new ArrayList<Integer>(); // Integer 是 Number 的子类
List<? extends Number> numberArray = new ArrayList<Double>();  // Double 是 Number 的子类

上面三个操作都是合法的, 因为 ? extends Number 规定了泛型通配符的上界, 即我们实际上的泛型必须要是 Number 类型或者是它的子类, 而 Number, Integer, Double 显然都是 Number 的子类(类型相同的也可以, 即这里我们可以认为 Number 是 Number 的子类).

子类型判断

假设有类型 G, 以及 SuperClass 和 SubClass 两个类, 并且 SuperClass 是 SubClass 的父类, 那么:

  • G<? extends SubClass> 是 G<? extends SuperClass> 的子类型. 如 List<? extends Integer> 是 List<? extends Number> 的子类型

  • G 是 G<? extends SuperClass> 的子类型, 例如 List 是 List<? extends Integer> 的子类型.

  • G<?> 和 G<? extends Object> 等同.

可以想象 G<? extends T> 为一个左闭右开的区间(T 在最左边), G<? extends Object> 是最大的区间, 当区间 G<? extends SuperClass> 包含 区间 G<? extends SubClass>时, 那么较大的区间就是父类.

关于读取

根据上面的例子, 对于 List<? extends Number> numberArray 对象:

  • 我们能够从 numberArray 中读取到 Number 对象, 因为 numberArray 中包含的元素是 Number 类型或 Number 的子类型.

  • 我们不能从 numberArray 中读取到 Integer 类型, 因为 numberArray 中可能保存的是 Double 类型.

  • 同理, 我们也不能从 numberArray 中读取到 Double 类型.

关于写入

根据上面的例子, 对于 List<? extends Number> numberArray 对象:

  • 我们不能添加 Number 到 numberArray 中, 因为 numberArray 有可能是List 类型

  • 我们不能添加 Integer 到 numberArray 中, 因为 numberArray 有可能是 List 类型

  • 我们不能添加 Double 到 numberArray 中, 因为 numberArray 有可能是 List 类型

即, 我们不能添加任何对象到 List<? extends T> 中, 因为我们不能确定一个 List<? extends T> 对象实际的类型是什么, 因此就不能确定插入的元素的类型是否和这个 List 匹配. List<? extends T> 唯一能保证的是我们从这个 list 中读取的元素一定是一个 T 类型的.

? super T

? super T 描述了通配符下界, 即具体的泛型参数需要满足条件: 泛型参数必须是 T 类型或它的父类, 例如:

// 在这里, Integer 可以认为是 Integer 的 "父类"
List<? super Integer> array = new ArrayList<Integer>();
// Number 是 Integer 的 父类
List<? super Integer> array = new ArrayList<Number>();
// Object 是 Integer 的 父类
List<? super Integer> array = new ArrayList<Object>();

关于读取

对于上面的例子中的 List<? super Integer> array 对象:

  • 我们不能保证可以从 array 对象中读取到 Integer 类型的数据, 因为 array 可能是 - List< Number > 类型的.
  • 我们不能保证可以从 array 对象中读取到 Number 类型的数据, 因为 array 可能是 List< Object > 类型的.
  • 唯一能够保证的是, 我们可以从 array 中获取到一个 Object 对象的实例.

关于写

对于上面的例子中的 List<? super Integer> array 对象:

  • 我们可以添加 Integer 对象到 array 中, 也可以添加 Integer 的子类对象到 array 中.

  • 我们不能添加 Double/Number/Object 等不是 Integer 的子类的对象到 array 中.

易混淆点

有一点需要注意的是, List<? super T> 和 List<? extends T> 中, 我们所说的 XX 是 T 的父类(a superclass of T) 或 XX 是 T 的子类(a subclass of T) 其实是针对于泛型参数而言的. 例如考虑如下例子:

List<? super Integer> l1 = ...
List<? extends Integer> l2 = ...

那么这里 ? super Integer 和 ? extends Integer 的限制是对谁的呢? 是表示我们可以插入任意的对象 X 到 l1 中, 只要 X 是 Integer 的父类? 是表示我们可以插入任意的对象 Y 到 l2 中, 只要 Y 是 Integer 的子类?
其实不是的, 我们必须要抛弃上面的概念, ? super Integer 和 ? extends Integer 限制的其实是 泛型参数, 即 List<? super Integer> l1 表示 l1 的泛型参数 T 必须要满足 T 是 Integer 的父类, 因此诸如 List< Object >, List< Number >的对象就可以赋值到 l1 中. 正因为我们知道了 l1 中的泛型参数的边界信息, 因此我们就可以向 l1 中添加 Integer 对象了, 推理过程如下:

令 T 是 l1 的泛型参数,:l1 = List<T> = List<? super Integer>
因此有 T 是 Integer 或 Integer 的父类.
如果 T 是 Integer, 则 l1 = List<Integer>, 显然我们可以添加任意的 Integer 对象或 Integer 的子类对象到 l1 中.
如果 T 是 Integer 的父类, 那么同理, 对于 Integer 或 Integer 的子类的对象, 我们也可以添加到 l1 中.

按同样的分析方式, List<? extends Integer> l2 表示的是 l2 的泛型参数是 Integer 的子类型. 而如果我们要给一个 List 插入一个元素的话, 我们需要保证此元素是 T 或是 T 的子类, 而这里 List<? extends Integer> l2, l2 的泛型参数是什么类型我们都不知道, 进而就不能确定 l2 的泛型参数的子类是哪些, 因此我们就不能向 l2 中添加任何的元素了.
来一个对比:

  • 对于 List<? super Integer> l1:

    • 正确的理解: ? super Integer 限定的是泛型参数. 令 l1 的泛型参数是 T, 则 T 是 Integer 或 Integer 的父类, 因此 Integer 或 Integer 的子类的对象就可以添加到 l1 中.

    • 错误的理解: ? super Integer限定的是插入的元素的类型, 因此只要是 Integer 或 Integer 的父类的对象都可以插入 l1 中

  • 对于 List<? extends Integer> l2:

    • 正确的理解: ? extends Integer 限定的是泛型参数. 令 l2 的泛型参数是 T, 则 T 是 Integer 或 Integer 的子类, 进而我们就不能找到一个类 X, 使得 X 是泛型参数 T 的子类, 因此我们就不可以向 l2 中添加元素. 不过由于我们知道了泛型参数 T 是 Integer 或 Integer 的子类这一点, 因此我们就可以从 l2 中读取到元素(取到的元素类型是 Integer 或 Integer 的子类), 并可以存放到 Integer 中.

    • 错误的理解: ? extends Integer 限定的是插入元素的类型, 因此只要是 Integer 或 Integer 的子类的对象都可以插入 l2 中

使用场景

PECS 原则: Producer Extends, Consumer Super

  • Producer extends: 如果我们需要一个 List 提供类型为 T 的数据(即希望从 List 中读取 T 类型的数据), 那么我们需要使用 ? extends T, 例如 List<? extends Integer>. 但是我们不能向这个 List 添加数据.

  • Consumer Super: 如果我们需要一个 List 来消费 T 类型的数据(即希望将 T 类型的数据写入 List 中), 那么我们需要使用 ? super T, 例如 List<? super Integer>. 但是这个 List 不能保证从它读取的数据的类型.

  • 如果我们既希望读取, 也希望写入, 那么我们就必须明确地声明泛型参数的类型, 例如 List< Integer >.
    例子:

public class Collections { public static <T> void copy(List<? super T> dest, List<? extends T> src) {for (int i=0; i<src.size(); i++) dest.set(i,src.get(i)); } 
}

上面的例子是一个拷贝数据的代码, src 是 List<? extends T> 类型的, 因此它可以读取出 T 类型的数据(读取的数据类型是 T 或是 T 的子类, 但是我们不能确切的知道它是什么类型, 唯一能确定的是读取的类型 is instance of T), , dest 是 List<? super T> 类型的, 因此它可以写入 T 类型或其父类的数据…

http://www.sczhlp.com/news/66014/

相关文章:

  • 网站的flash咸阳做网站费用
  • 珠海网站建设q479185700强涵京东的网站规划与建设
  • 我的世界做圆网站中山网站seo优化
  • 解码 - Great Mind by Gemini 2.5 Pro
  • 网站标题如何书写怎么建自己的手机网站吗
  • 网站改成html5seo免费自学的网站
  • 沧州市网站制作公司网站建设制作 优帮云
  • 网站建成谷歌排名推广公司
  • 源代码代做网站建设企业营销型网站
  • 医院网站备案流程火星时代教育培训机构学费多少
  • 20250903 S2模拟赛
  • 【构造】CF2090D Simple Permutation
  • 印度股票数据API对接文档
  • CDN 网站是否需要重新备案网站浮动广告代码
  • seo网站推广方法德宏网页设计
  • 建设银行网站会员网站名称意义
  • 马鞍山网站设计购物网站模板html
  • 企业网站做优化排名象客做网站公司排行
  • 怎么自己建设一个网站外贸推广平台
  • 分布式网站架构php购物网站开发设计
  • 国外html5网站模版专业的做pc端网站
  • 网站排名诊断平面设计师如何做网站
  • 计算机应用技术php网站开发深圳做网站专业
  • 网上购物网站开发背景php网站开发工程师面试
  • lc1016-子串能表示从1到N数字的二进制串
  • 建设银行广西分行招聘网站电子商务网站建设报告分析
  • 简单网站的代码青岛知道网络科技有限公司
  • 南阳南阳新区网站建设摄影网站制作教程
  • waP六感程序建设网站网建公司浅谈网站建设的目的和意义
  • 黄页网页的推广网站下载网站注册价格