java理论与实践--使用通配符简化泛型使用

java理论与实践--使用通配符简化泛型使用

ID:8820164

大小:52.50 KB

页数:5页

时间:2018-04-08

java理论与实践--使用通配符简化泛型使用_第1页
java理论与实践--使用通配符简化泛型使用_第2页
java理论与实践--使用通配符简化泛型使用_第3页
java理论与实践--使用通配符简化泛型使用_第4页
java理论与实践--使用通配符简化泛型使用_第5页
资源描述:

《java理论与实践--使用通配符简化泛型使用》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库

1、Java理论与实践:使用通配符简化泛型使用通配符是Java™语言中最复杂的泛型之一,特别是围绕捕获通配符的处理和令人困惑的错误消息。在这一期的Java理论与实践中,资深Java开发人员BrianGoetz解释了一些由javac生成的怪异错误消息并提供了一些简化泛型使用的技巧和解决方法。自从泛型被添加到JDK5语言以来,它一直都是一个颇具争议的话题。一部分人认为泛型简化了编程,扩展了类型系统从而使编译器能够检验类型安全;另外一些人认为泛型添加了很多不必要的复杂性。对于泛型我们都经历过一些痛苦的回忆,但毫无

2、疑问通配符是最棘手的部分。通配符基本介绍泛型是一种表示类或方法行为对于未知类型的类型约束的方法,比如“不管这个方法的参数x和y是哪种类型,它们必须是相同的类型”,“必须为这些方法提供同一类型的参数”或者“foo()的返回值和bar()的参数是同一类型的”。通配符—使用一个奇怪的问号表示类型参数—是一种表示未知类型的类型约束的方法。通配符并不包含在最初的泛型设计中(起源于GenericJava(GJ)项目),从形成JSR14到发布其最终版本之间的五年多时间内完成设计过程并被添加到了泛型中。通配符在类型系统

3、中具有重要的意义,它为一个泛型类所指定的类型集合提供了一个有用的类型范围。对泛型类ArrayList而言,对于任意(引用)类型T,ArrayList类型是ArrayList的超类型(类似原始类型ArrayList和根类型Object,但是这些超类型在执行类型推断方面不是很有用)。通配符类型List与原始类型List和具体类型List都不相同。如果说变量x具有List类型,这表示存在一些T类型,其中x是List类型,x具有相同的结构,尽管我们不知道其元素的具体

4、类型。这并不表示它可以具有任意内容,而是指我们并不了解内容的类型限制是什么—但我们知道存在某种限制。另一方面,原始类型List是异构的,我们不能对其元素有任何类型限制,具体类型List表示我们明确地知道它能包含任何对象(当然,泛型的类型系统没有“列表内容”的概念,但可以从List之类的集合类型轻松地理解泛型)。通配符在类型系统中的作用部分来自其不会发生协变(covariant)这一特性。数组是协变的,因为Integer是Number的子类型,数组类型Integer[]是Number[]的

5、子类型,因此在任何需要Number[]值的地方都可以提供一个Integer[]值。另一方面,泛型不是协变的,List不是List的子类型,试图在要求List的位置提供List是一个类型错误。这不算很严重的问题—也不是所有人都认为的错误—但泛型和数组的不同行为的确引起了许多混乱。我已使用了一个通配符—接下来呢?清单1展示了一个简单的容器(container)类型Box,它支持put和get操作。Box由类型参数T参数化,该参数表示Box内

6、容的类型,Box只能包含String类型的元素。清单1.简单的泛型Box类型publicinterfaceBox{publicTget();publicvoidput(Telement);}通配符的一个好处是允许编写可以操作泛型类型变量的代码,并且不需要了解其具体类型。例如,假设有一个Box类型的变量,比如清单2unbox()方法中的box参数。unbox()如何处理已传递的box?清单2.带有通配符参数的Unbox方法publicvoidunbox(Boxbox){S

7、ystem.out.println(box.get());}事实证明Unbox方法能做许多工作:它能调用get()方法,并且能调用任何从Object继承而来的方法(比如hashCode())。它惟一不能做的事是调用put()方法,这是因为在不知道该Box实例的类型参数T的情况下它不能检验这个操作的安全性。由于box是一个Box而不是一个原始的Box,编译器知道存在一些T充当box的类型参数,但由于不知道T具体是什么,您不能调用put()因为不能检验这么做不会违反Box的类型安全限制(实际上,您可以

8、在一个特殊的情况下调用put():当您传递null字母时。我们可能不知道T类型代表什么,但我们知道null字母对任何引用类型而言是一个空值)。关于box.get()的返回类型,unbox()了解哪些内容呢?它知道box.get()是某些未知T的T,因此它可以推断出get()的返回类型是T的擦除(erasure),对于一个无上限的通配符就是Object。因此清单2中的表达式box.get()具有Object类型。通配符捕获清单3展示了一些似乎

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。