分享
 
 
 

准备好迎接泛型

王朝java/jsp·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

准备好迎接泛型

Articles Index

泛型介绍

作者:Paul Mingardi

November 2003

泛型已经在其他的语言中使用了很多年了,通常也被称为参数化类型。现在在广大Java开发人员的要求下,泛型终于被添加进了Java语言中,并且将伴随J2SE1.5一起发布。

Lists的问题

有了泛型,容器类型(例如Lists)将不是用来操作指定类型的数据,而是根据容器定义的时候指定的数据类型来操作一组同质(homogeneous)的数据。这样对Java开发人员有什么帮助呢?

理解泛型的最好的办法是看看一些将从泛型中得到好处的代码。下面的的例子是用当前的Java语言规范写的(不带泛型),包含了一个String类型元素的List和Integer类型(不是基本类型int)元素的List。因为两个元素都是Object类的子类,并且Java有多态引用,所以你可以往List里面塞任何的类型。不幸的事情即将发生,从编译器的角度来看,两个List中的元素都是Object类型的,所以唯一能区别两个List中的类型的方法就是使用运行时类型识别(即使用转型cast)。更坏的事情是,如果一个开发人员混淆了两个List中元素的类型并且执行了一个非法的转型,这样的错误只有在运行时才能被发现。

下面是这样的一段代码。在第一个例子中(第13行到20行),你可能会确信你是在操作一个Integer类型的List,虽然事实上是一个String类型的List。在第二部分(第11行和22到27行),你可能以为你在对同质的String类型进行操作,但事实上这是一个混合了String和Integer类型的异质List。除非你为每个元素类型建立一个List(这样其实是破坏了面向对象的特性),你将无法静态的限制List只能容纳同质的元素。在这个例子中,这样的错误还很容易就被发现,但是在一个大型的系统中,这将是你的一个大问题。

1..

2. List stringList = new LinkedList();

3. List integerList = new LinkedList();

4.

5. integerList.add(new Integer(1));

6. integerList.add(new Integer(2));

7.

8. stringList.add(new String("I am a String"));

9.

10. // 没什么能限制元素是同质的

11. stringList.add(new Integer(1));

12.

13. Iterator listIterator = integerList.iterator();

14.

15. // 编译器不关心List的返回类型和不合法的转型

16. // 开发人员本意是想遍历String的这个List

17. while(listIterator.hasNext()) {

18.

19. // 只有在运行时才能捕捉到这个不合法的转型错误。

20. String item = (String)listIterator.next();

21. }

22.

23. listIterator = stringList.iterator();

24. // 没有同质元素的保证

25. while (listIterator.hasNext()) {

26. // 因为异质元素,将导致运行时错误

27. String item = (String)listIterator.next();

28. }

29..

泛型的优点

有了泛型,你就能得到和上面的例子所要的动态特性,有了一个很强的静态类型检查,编译器知道两个List的不同,因为他们容纳不同类型的元素,并且每个List只能容纳同质的一组元素。下面的例子对上面的代码有了一些改进,使用了泛型。你可以在注释中看到,所有的错误都在编译时被捕捉了。先不要去关心语法,在下面我们将讨论到语法。

对比两个例子,你就会注意到,在泛型中添加了额外的类型信息,这些信息将指引编译器去检查容器中应该包含什么类型的数据。

1..

2. import java.util.LinkedList;

3. import java.util.Collections;

4. import java.util.Iterator;

5.

6. public class genericsExample2{

7.

8. static public void main(String[] args) {

9. LinkedList<String> stringList = new LinkedList<String>();

10. LinkedList<Integer> integerList = new LinkedList<Integer>();

11.

12. integerList.add(new Integer(1));

13. integerList.add(new Integer(2));

14.

15. stringList.add(new String("I am a String"));

16. stringList.add(new Integer(1)); // 这将导致一个编译错误

17.

18. /* genericsExample2.java:16: cannot resolve symbol

19. ** symbol : method add (java.lang.Integer)

20. */

21.

22. Iterator<Integer> listIterator = integerList.iterator();

23. String item;

24. while(listIterator.hasNext()) {

25. item = listIterator.next(); // 这将导致一个编译错误

26.

27. /* genericsExample2.java:25: incompatible types

28. ** found : java.lang.Integer

29. ** required: java.lang.String

30. */

31. }

32.

33. listIterator = stringList.iterator(); // 这将导致一个编译错误

34.

35. /* genericsExample2.java:33: incompatible types

36. ** found : java.util.Iterator<java.lang.String>

37. ** required: java.util.Iterator<java.lang.Integer>

38. */

39. // the iterator is guaranteed to be homogeneous

40. while (listIterator.hasNext()) {

41. item = listIterator.next();

42.

43. /* genericsEx2.java:41: incompatible types

44. ** found : java.lang.Integer

45. ** required: java.lang.String

46. */

47. }

48. } // main

49. } // class genericsExample2

通过这个例子,你应该能明白为什么泛型是对Java语言的改进中呼声最高的。下面是一些使用泛型后的好处:

通过静态类型检查来获得平滑的动态绑定。编译时发现的错误比运行时发生的错误容易纠正。

容器的模棱两可性减少了,代码的可读性增强了。

使用更少的转型使得代码更加清晰。

基本语法一览

到这,你只看到了泛型化的容器类,其实你可以声明泛型化的接口,类,和方法,下面描述了你可能会用到的语法。

语法

参数化类型(Paramaterized Type)

Vector<String> stringVector = new Vector<String>

List<Integer> integerList = new List<Integer>

接口(Interface)

interface List<Element> implements MyInterface{...}

类(Class)

class MyList<Element> {...}

class MyList<Element> implements List<Element> {...}

方法(Method)

boolean containsBoth(Element a, Element b);

static <Element> boolean swap(List<Element> list, int i, int j);

下面的代码使用类似的语法:MyInterface

开发使用泛型

关于泛型更多的信息,你可以参考JSR14的声明(specification and to the JSR 14)。开发人员今天就可以通过Sun公司提供的实现了泛型的原型编译器来使用泛型代码。这个原型包含了:用扩展后的语言写的范例原代码,一个编译时候需要用到的jar包,一个包含了容器类型的一部分,还包含了一些范例程序和makefile 来帮助编译代码和调用JVM。下面是用C-shell的一些步骤。

下载泛型原型的压缩包

如果你还不是一个Java Developer Connection的成员,那么你需要注册一下才能下载。

解压缩包到安装目录/install_dir

- unzip adding_generics-1_3-ea.zip

下载并安装 JDK 1.4.1

设置环境变量

setenv JSR14DISTR /install_dir/jsr14_adding_generics-1_3-ea

setenv J2SE14 /jdk_install_dir

运行例子

cd /install_dir/jsr14_adding_generics-1_3-ea/examples

Compile and run the Test.java sample using the makefile.

- make

参考

Early Access Prototype for JSR-14

JSR 14 Specification

关于作者

Paul Mingardi 是Sun公司的市场开发工程师,对合作伙伴例如健康关心, 银行和金融方面的技术支持。同时他也和独立软件供应商合作,来帮助他们更加成功的应用Java和其他的Sun的技术。Paul是Sun认证的企业架构师(Sun Certified Enterprise Architect)并且同时拥有7个认证。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有