当前位置:七道奇文章资讯编程技术Java编程
日期:2011-03-22 16:14:00  来源:本站整理

Java理论与实践: 操纵通配符简化泛型操纵[Java编程]

赞助商链接



  本文“Java理论与实践: 操纵通配符简化泛型操纵[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:

自从泛型被增添到 JDK 5 语言以来,它一向都是一个颇具争议的话题.一部 分人认为泛型简化了编程,扩大了范例系统从而使编译器可以查验范例安全;另 外一些人认为泛型增添了很多不必要的复杂性.关于泛型我们都阅历过一些痛楚 的回想,但毫无疑问通配符是最棘手的部份.

通配符基本介绍

泛型是一种表示类或办法行为关于未知范例的范例约束的办法,比方 “不管 这个办法的参数 x 和 y 是哪类范例,它们必须是相同的范例”,“必须为这些 办法供应同一范例的参数” 大概 “foo() 的返回值和 bar() 的参数是同一类 型的”.

通配符 — 利用一个奇特的问号表示范例参数 — 是一种表示未知范例的类 型约束的办法.通配符并不包含在最初的泛型计划中(发源于 Generic Java (GJ)项目),从形成 JSR 14 到公布其终究版本之间的五年多时间内完成计划 历程并被增添到了泛型中.

通配符在范例系统中具有重要的意义,它们为一个泛型类所指定的范例调集 供应了一个有效的范例范围.对泛型类 ArrayList 而言,关于肆意(引用)类 型 T,ArrayList<?> 范例是 ArrayList<T> 的超范例(近似原始 范例 ArrayList 和根范例 Object,但是这些超范例在履行范例推断方面不是很 有效).

通配符范例 List<?> 与原始范例 List 和具体范例 List<Object> 都不相同.假如说变量 x 具有 List<?> 范例,这 表示存在一些 T 范例,此中 x 是 List<T>范例,x 具有相同的构造,尽 管我们不知道其元素的具体范例.这并不表示它可以具有肆意内容,而是指我们 并不理解内容的范例限制是什么 — 但我们知道存在 某种限制.另一方面,原 始范例 List 是异构的,我们不能对其元素有任何范例限制,具体范例 List<Object> 表示我们明确地知道它能包含任何对象(当然,泛型的类 型系统没有 “列表内容” 的概念,但可以从 List 之类的调集范例轻松地理解 泛型).

通配符在范例系统中的作用部份来自其不会发生协变(covariant)这一特点 .数组是协变的,因为 Integer 是 Number 的子范例,数组范例 Integer[] 是 Number[] 的子范例,因此在任何需求 Number[] 值的地方都可以供应一个 Integer[] 值.另一方面,泛型不是协变的, List<Integer> 不是 List<Number> 的子范例,试图在要求 List<Number> 的位置供应 List<Integer> 是一个范例错误.这不算很严重的问题 — 也不是全部人 都认为的错误 — 但泛型和数组的差别行为的确惹起了很多混乱.

我已利用了一个通配符 — 接下来呢?

清单 1 展示了一个简单的容器(container)范例 Box,它支持 put 和 get 操作. Box 由范例参数 T 参数化,该参数表示 Box 内容的范例, Box<String> 只能包含 String 范例的元素.

清单 1. 简单的泛型 Box 范例

public interface Box<T> {
   public T get();
   public void put(T element);
}

通配符的一个好处是答应编写可以操作泛型范例变量的代码,并且不需求了 解其具体范例.比方,假定有一个 Box<?> 范例的变量,比方清单 2 unbox() 办法中的 box 参数.unbox() 若何处理已传送的 box?

清单 2. 带有通配符参数的 Unbox 办法

public void unbox(Box<?> box) {
   System.out.println(box.get());
}

事实证明 Unbox 办法能做很多工作:它能调用 get() 办法,并且能调用任 何从 Object 担当而来的办法(比方 hashCode()).它惟一不能做的事是调用 put() 办法,这是因为在不知道该 Box 实例的范例参数 T 的情形下它不能查验 这个操作的安全性.由于 box 是一个 Box<?> 而不是一个原始的 Box, 编译器知道存在一些 T 充当 box 的范例参数,但由于不知道 T 具体是什么, 您不能调用 put() 因为不能查验这么做不会违反 Box 的范例安全限制(实际上 ,您可以在一个特别的情形下调用 put():当您传送 null 字母时.我们大概不 知道 T 范例代表什么,但我们知道 null 字母对任何引用范例而言是一个空值 ).

关于 box.get() 的返回范例,unbox() 理解哪些内容呢?它知道 box.get() 是某些未知 T 的 T,因此它可以推断出 get() 的返回范例是 T 的擦除 (erasure),关于一个无上限的通配符就是 Object.因此清单 2 中的表达式 box.get() 具有 Object 范例.


  以上是“Java理论与实践: 操纵通配符简化泛型操纵[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:

  • 利用Javascript实现网页水印(非图片水印)
  • Java开辟环境的搭建
  • Ubuntu java安装与配置
  • 办理Ubuntu 10.04 Firefox3.6 Java浏览器插件不工作的问
  • Ubuntu重装后Java环境的设置
  • Sun Java进入Ubuntu 10.10软件中央
  • Ubuntu 10.10配置Java开辟环境
  • 在Ubuntu 10.10中配置Java环境变量的办法
  • Ubuntu下Java环境的搭建
  • Ubuntu 10.04 下安装 Java, JRE
  • Ubuntu 10.04下的搭建SUN JAVA开辟环境
  • Ubuntu 12.04安装java7
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .