ImageVerifierCode 换一换
格式:DOCX , 页数:46 ,大小:37.43KB ,
资源ID:22940681      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/22940681.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(JAVA5泛型和反射Word下载.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

JAVA5泛型和反射Word下载.docx

1、在对检索到的值进行任何特定于 String 的操作之前,必须将它强制转换为 String,即使是将检索到的元素添加到同一代码块中,也是如此!清单 2. 将检索到的值强制转换成 Stringimport java.util.Hashtable;class Test public static void main(String args) Hashtable h = new Hashtable(); h.put(new Integer(0), value); String s = (String)h.get(new Integer(0); System.out.println(s); 请注意 ma

2、in 方法主体部分的第三行中需要进行的数据类型转换。因为 Java 类型系统相当薄弱,因此代码会因象上面那样的数据类型转换而漏洞百出。这些数据类型转换不仅使 Java 代码变得更加拖沓冗长,而且它们还降低了静态类型检查的价值(因为每个数据类型转换都是一个选择忽略静态类型检查的伪指令)。我们该如何扩展该类型系统,从而不必回避它呢?用泛型类型来解决问题!要消除如上所述的数据类型转换,有一种普遍的方法,就是用泛型类型来增大 Java 类型系统。可以将泛型类型看作是类型“函数”;它们通过类型变量进行参数化,这些类型变量可以根据上下文用各种类型参数进行实例化。例如,与简单地定义类 Hashtable 不

3、同,我们可以定义泛型类 Hashtable,其中 Key 和 Value 是类型参数。除了类名后跟着尖括号括起来的一系列类型参数声明之外,在 Tiger 中定义这样的泛型类的语法和用于定义普通类的语法很相似。例如,可以按照如下所示的那样定义自己的泛型 Hashtable 类:清单 3. 定义泛型 Hashtable 类class Hashtable . 然后可以引用这些类型参数,就像我们在类定义主体内引用普通类型那样,如下所示:清单 4. 像引用普通类型那样引用类型参数 Value put(Key k, Value v) . Value get(Key k) .类型参数的作用域就是相应类定义的

4、主体部分(除了静态成员之外)(在下一篇文章中,我们将讨论为何 Tiger 实现中有这样的“怪习”,即必须对静态成员进行此项限制。请留意!)。创建一个新的 Hashtable 实例时,必须传递类型参数以指定 Key 和 Value 的类型。传递类型参数的方式取决于我们打算如何使用 Hashtable。在上面的示例中,我们真正想要做的是创建 Hashtable 实例,它只将 Integer 映射为 String。可以用新的 Hashtable 类来完成这件事:清单 5. 创建将 Integer 映射为 String 的实例 Hashtable h = new Hashtable();现在不再需要数

5、据类型转换了。请注意用来实例化泛型类 Hashtable 的语法。就像泛型类的类型参数用尖括号括起来那样,泛型类型应用程序的参数也是用尖括号括起来的。清单 6. 除去不必要的数据类型转换.String s = h.get(keySystem.out.println(s);当然,程序员若只是为了能使用泛型类型而必须重新定义所有的标准实用程序类(比如 Hashtable 和 List)的话,则可能会是一项浩大的工程。幸好,Tiger 为用户提供了所有 Java 集合类的泛型版本,因此我们不必自己动手来重新定义它们了。此外,这些类能与旧代码和新的泛型代码一起无缝工作(下个月,我们会说明如何做到这一点

6、)。Tiger 的基本类型限制Tiger 中类型变量的限制之一就是,它们必须用引用类型进行实例化 基本类型不起作用。因此,在上面这个示例中,无法完成创建从 int 映射到 String 的 Hashtable。这很遗憾,因为这意味着只要您想把基本类型用作泛型类型的参数,您就必须把它们组装为对象。另一方面,当前的这种情况是最糟的;您不能将 int 作为键传递给 Hashtable,因为所有的键都必须是 Object 类型。我们真正想看到的是,基本类型可以自动进行包装(boxing)和解包装(unboxing),类似于用 C# 所进行的操作(或者比后者更好)。遗憾的是,Tiger 不打算包括基本类

7、型的自动包装(但是人们可以一直期待 Java 1.6 中出现该功能!受限泛型有时我们想限制可能出现的泛型类的类型实例化。在上面这个示例中,类 Hashtable 的类型参数可以用我们想用的任何类型参数进行实例化,但是对于其它某些类,我们或许想将可能的类型参数集限定为给定类型范围内的子类型。例如,我们可能想定义泛型 ScrollPane 类,它引用普通的带有滚动条功能的 Pane。被包含的 Pane 的运行时类型通常会是类 Pane 的子类型,但是静态类型就只是 Pane。有时我们想用 getter 检索被包含的 Pane,但是希望 getter 的返回类型尽可能具体些。我们可能想将类型参数 M

8、yPane 添加到 ScrollPane 中,该类型参数可以用 Pane 的任何子类进行实例化。然后可以用这种形式的子句:extends Bound 来说明 MyPane 的声明,从而来设定 MyPane 的范围:清单 7. 用 extends 子句来说明 MyPane 声明class ScrollPane当然,我们可以完全不使用显式的范围,只要能确保没有用不适当的类型来实例化类型参数。为什么要自找麻烦在类型参数上设定范围呢?这里有两个原因。首先,范围使我们增加了静态类型检查功能。有了静态类型检查,就能保证泛型类型的每次实例化都符合所设定的范围。其次,因为我们知道类型参数的每次实例化都是这个范

9、围之内的子类,所以可以放心地调用类型参数实例出现在这个范围之内的任何方法。如果没有对参数设定显式的范围,那么缺省情况下范围是 Object,这意味着我们不能调用范围实例在 Object 中未曾出现的任何方法。多态方法除了用类型参数对类进行参数化之外,用类型参数对方法进行参数化往往也同样很有用。泛型 Java 编程用语中,用类型进行参数化的方法被称为多态方法(Polymorphic method)。多态方法之所以有用,是因为有时候,在一些我们想执行的操作中,参数与返回值之间的类型相关性原本就是泛型的,但是这个泛型性质不依赖于任何类级的类型信息,而且对于各个方法调用都不相同。例如,假定想将 fac

10、tory 方法添加到 List 类中。这个静态方法只带一个参数,也将是 List 唯一的元素(直到添加了其它元素)。因为我们希望 List 成为其所包含的元素类型的泛型,所以希望静态 factory 方法带有类型变量 T 这一参数并返回 List 的实例。但是我们确实希望该类型变量 T 能在方法级别上进行声明,因为它会随每次单独的方法调用而发生改变(而且,正如我在下一篇文章中将讨论的那样,Tiger 设计的“怪习”规定静态成员不在类级类型参数的范畴之内)。Tiger 让我们通过将类型参数作为方法声明的前缀,从而在单独的方法级别上声明类型参数。例如,可以按照如下所示的那样为 factory 方法

11、 make 添加前缀:清单 8. 将类型参数作为前缀添加到方法声明class Utilities public static List make(T first) return new List(first);除了多态方法中所增加的灵活性之外,Tiger 中还增加了一个优点。Tiger 使用类型推断机制,根据参数类型来自动推断出多态方法的类型。这可以大大减少方法调用的繁琐和复杂性。例如,如果想调用 make 方法来构造包含 new Integer(0) 的 List 新实例,那么只需编写:清单 9. 强制 make 构造新实例Utilities.make(Integer(0)然后会自动地从方法

12、参数中推断出类型参数的实例化。结束语正如我们所见到的那样,在 Java 语言中添加泛型类型肯定会大大增强我们使用静态类型系统的能力。学习如何使用泛型类型相当简单,但是同样也需要避免一些缺陷。在接下来的文章中,我们将讨论如何充分使用将出现在 Tiger 中的泛型类型的特定表现,以及一些缺陷。我们还将研究对泛型 Java 类型工具的扩展,我们期盼这些工具可以出现在仍处于设计阶段的 Java 平台之中。一、逐渐深入泛型1、没有任何重构的原始代码:有两个类如下,要构造两个类的对象,并打印出各自的成员x。public class StringFoo private String x; public St

13、ringFoo(String x) this.x = x; public String getX() return x; public void setX(String x) public class DoubleFoo private Double x; public DoubleFoo(Double x) public Double getX() public void setX(Double x) 以上的代码是在无聊,就不写如何实现了。2、对上面的两个类进行重构,写成一个类:因为上面的类中,成员和方法的逻辑都一样,就是类型不一样,因此考虑重构。Object是所有类的父类,因此可以考虑用O

14、bject做为成员类型,这样就可以实现通用了,实际上就是“Object泛型”,暂时这么称呼。public class ObjectFoo private Object x; public ObjectFoo(Object x) public Object getX() public void setX(Object x) 写出Demo方法如下:public class ObjectFooDemo public static void main(String args) ObjectFoo strFoo = new ObjectFoo(Hello Generics! ObjectFoo douF

15、oo = new ObjectFoo(new Double(33); ObjectFoo objFoo = new ObjectFoo(new Object(); System.out.println(strFoo.getX=+(String)strFoo.getX();douFoo.getX=+(Double)douFoo.getX();objFoo.getX=+(Object)objFoo.getX();运行结果如下:strFoo.getX=Hello Generics!douFoo.getX=33.0objFoo.getX=java.lang.Object19821f解说:在Java 5

16、之前,为了让类有通用性,往往将参数类型、返回类型设置为Object类型,当获取这些返回类型来使用时候,必须将其“强制”转换为原有的类型或者接口,然后才可以调用对象上的方法。3、Java5泛型来实现强制类型转换很麻烦,我还要事先知道各个Object具体类型是什么,才能做出正确转换。否则,要是转换的类型不对,比如将“Hello Generics!”字符串强制转换为Double,那么编译的时候不会报错,可是运行的时候就挂了。那有没有不强制转换的办法-有,改用 Java5泛型来实现。public class GenericsFoo private T x; public GenericsFoo(T x

17、) public T getX() public void setX(T x) public class GenericsFooDemo public static void main(String args) GenericsFoo strFoo=new GenericsFoo douFoo=new GenericsFoo objFoo=new GenericsFoo(new Object();+strFoo.getX();+douFoo.getX();+objFoo.getX();运行结果:和使用“Object泛型”方式实现结果的完全一样,但是这个Demo简单多了,里面没有强制类型转换信息

18、。下面解释一下上面泛型类的语法:使用来声明一个类型持有者名称,然后就可以把T当作一个类型代表来声明成员、参数和返回值类型。当然T仅仅是个名字,这个名字可以自行定义。class GenericsFoo 声明了一个泛型类,这个T没有任何限制,实际上相当于Object类型,实际上相当于 class GenericsFoo。与Object泛型类相比,使用泛型所定义的类在声明和构造实例的时候,可以使用“”来一并指定泛型类型持有者的真实类型。类如GenericsFoo当然,也可以在构造对象的时候不使用尖括号指定泛型类型的真实类型,但是你在使用该对象的时候,就需要强制转换了。比如:GenericsFoo d

19、ouFoo=new GenericsFoo(new Double(实际上,当构造对象时不指定类型信息的时候,默认会使用Object类型,这也是要强制转换的原因。二、泛型的高级应用1、限制泛型的可用类型在上面的例子中,由于没有限制class GenericsFoo,这样类中的泛型T只能是Collection接口的实现类,传入非Collection接口编译会出错。注意:这里的限定使用关键字 extends,后面可以是类也可以是接口。但这里的extends已经不是继承的含义了,应该理解为T类型是实现Collection接口的类型,或者T是继承了XX类的类型。下面继续对上面的例子改进,我只要实现了集合

20、接口的类型:public class CollectionGenFoo public CollectionGenFoo(T x) 实例化的时候可以这么写:public class CollectionGenFooDemo CollectionGenFoo listFoo = null; listFoo = new CollectionGenFoo listFoo=new CollectionGenFoo实例化成功!当前看到的这个写法是可以编译通过,并运行成功。可是注释掉的两行加上就出错了,因为这么定义类型的时候,就限定了构造此类实例的时候T是确定的一个类型,这个类型实现了Collection接口,但是实现 Collection接口的类很多很多,如果针对每一种都要写出具体的子类类型,那也太麻烦了,我干脆还不如用Object通用一下。别急,泛型针对这种 情况还有更好的解决方案,那就是“通配符泛型”。2、通配符泛型为了解决类型被限制死了不能动态根据实例来确定的缺点,引入了“通配符泛型”,针对上面的例子,使用通配泛型格式为,“?”代表未知类型,这个类型是实现Collection接口。那么上面实现的方式可以写为: /现在不会出错了 listFoo1 = null;1、如果只指定了,而没有extends,则默认是允许Obje

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1