泛型.docx
- 文档编号:17696585
- 上传时间:2023-08-03
- 格式:DOCX
- 页数:16
- 大小:118.69KB
泛型.docx
《泛型.docx》由会员分享,可在线阅读,更多相关《泛型.docx(16页珍藏版)》请在冰点文库上搜索。
泛型
型(Generics)简介
J2SE5.0中的最显著的变化之一是添加对泛型类型的支持.在J2SE1.4以及之前的版本中,Java程序并不是类型安全的.例如,Collectionframework中定义的List,Map等容器类的元素都是Object类型,即这个类包含的元素是Object对象.使用这种方式实现的列表,可以用来操作整数,实数,字符串或者任何对象类型.例如
清单1.1类型不安全的代码示例
ListstringList=newArrayList();
stringList.add("abcde");
Stringstr=(String)stringList.get(0);
这种方法实现的列表需要使用强制类型转换(又称显示造型),因此不是类型安全的.在上面这段代码种,虽然变量名为stringList,但是我们仍然可以把一个整型对象添加到这个队列中,例如,
清单1.2类型不安全的代码示例
stringList.add(newInteger(5));
在这种情况下,从字符列表中获取对象时,强制类型转换就会导致运行时异常.
清单1.3类型不安全的代码示例
Stringstr=(String)stringList.get
(1);//runtimeexception
泛型是Java迈向类型安全的一个重要步骤,使用泛型可以构造出类型安全的代码.
声明泛型
所谓泛型是指类型参数化(parameterizedtypes).Java是一种强类型的语言,在J2SE1.4以及以前的版本中,我们在定义一个Java类,接口或者方法的时候,必须指定变量的类型.在声明泛型类、接口或者函数时,定义变量的时候不指定某些变量的具体类型,而是用一个类型参数代替.在使用这个类,接口,或者方法的时候,这个类型参数由一个具体类型所代替.
2.1泛型类
下面的例子中介绍了如何创建一个最简单泛型类
清单2.1,最简单的泛型类
publicclassGenSample
类名后面带有
下面通过一个列表的例子来具体说明如果声明泛型类和类型参数的用法.
清单2.2,泛型列表
publicclassGenList
privateT[]elements;
privateintsize=0;
privateintlength=0;
publicGenList(intsize){
elements=(T[])newObject[size];
this.size=size;
}
publicTget(inti){
if(i returnelements[i]; } returnnull; } publicvoidadd(Te){ if(length elements[length++]=e; } } 在列表的例子中,类型参数T被用来表示列表中的元素的类型,即,这个列表中的元素是T类型的. 在使用这个列表时,这个类型参数T会被具体的类型所替代. 注意,由于T时类型参数不是具体的类,所以不能使用new操作符创建T的对象,例如newT(),或者,newT[10]. 2.2泛型接口 在J2SE5.0中,不仅仅可以声明泛型类,也可以声明泛型接口,声明泛型接口和声明泛型类的语法类似,也是在接口命称后面加上 清单3.2.3,泛型接口 publicinterfaceGenInterface voidfunc(Tt); } 2.3、声明多个类型参数的泛型类或者接口 在声明泛型类的时候,可是使用多个类型参数.多个类型参数之间用逗号分开,例如, 清单3.2.4,多个类型参数的泛型类 publicclassGenMap Eclipse3.1的类创建向导支持创建泛型类,如下图所示, 图2.1使用类向导创建泛型类 使用Eclipse接口向导创建泛型接口 图2.2使用接口向导创建泛型接口 2.4泛型方法 类型参数(typeparameter)不仅仅可以用来声明泛型类或者泛型接口,也可以用来声明泛型方法,而且这种声明的泛型方法可以用在非泛型类中,声明泛型方法的一般格式是 清单2.5泛型方法的一般形式 清单3.2.6泛型方法示例 public returnobj.toString(); } 2.5受限泛型 受限泛型是指类型参数的取值范围是受到限制的.extends关键字不仅仅可以用来声明类的继承关系,也可以用来声明类型参数(typeparameter)的受限关系.例如,我们只需要一个存放数字的列表,包括整数(Long,Integer,Short),实数(Double,Float),不能用来存放其他类型,例如字符串(String),也就是说,要把类型参数T的取值泛型限制在Number极其子类中.在这种情况下,我们就可以使用extends关键字把类型参数(typeparameter)限制为数字, 清单2.7受限泛型示例 publicclassLimited publicstaticvoidmain(String[]args){ Limited Limited } } 在Eclipse3.1中,上例中的编译错误信息如下图所示 图2.3由于受限泛型导致的编译错误 在程序中使用泛型 3.1在程序中使用泛型类 在创建泛型类的对象的时候,和创建普通对象基本类似,必须提供具体的类类型来替代类型参数T(J2SE5.0目前不支持原始类型作为类型参数(typeparameter)). 清单3.1,使用泛型类 //如果需要整型的列表 GenList //如果需要字符型的列表 GenList //不能使用原始类型 GenList 3.2使用泛型解决类型安全性问题 使用泛型实现的列表是类型安全的,下列破坏类型安全语句会在编译的时候检查出来。 把鼠标放在错误标记上,Eclipse3.1中的错误提示就会显示,如下图所示: 图3.3.2破坏类型安全引起的错误 3.3二义性错误 GenMap在声明是使用了2个类型参数T和V,因此在创建GenMap的对象的时候也需要提供2个具体的类类型来替代这2个类型参数,例如, 清单9,多个参数的泛型类 GenMap GenMap 上例中,T和V虽然看起来是两个不同的类型参数,但是在使用这个泛型类的时候,T和V很有可能被替换成同一种类型.因此在声明多个类型参数的泛型类时,要注意避免这种二义性错误,例如, 清单10,二义性错误 publicclassGenMap //编译错误,二义性错误 publicvoidset(Tt){} publicvoidset(Vv){} } 在上面这段代码,如果T和V被替换成同一种类型,set函数的签名(signature)就是完全一样的,所以编译器会报告二义性错误.正确的用法是声明2个不同名的方法,例如, 清单10,二义性错误 publicclassGenMap publicvoidsetKey(Tt){} publicvoidsetValue(Vv){} } 图3.3二义性错误 3.4使用通配符 前面我们创建了泛型的列表,如果我需要一个方法来处理泛型列表,例如,我们希望把列表中的每个元素都打印出来,但是类型参数(typeparameter)只能使用在声明一个泛型类的时候,如果类型参数使用在函数定义里会导致编译错误。 publicstaticvoidprint(GenList 在这种情况下,我们需要用另外一种方法来表示一个泛型类,否则,就可能需要书写多个print函数。 publicstaticvoidprint(GenList publicstaticvoidprint(GenList … publicstaticvoidprint(GenList J2SE5.0中提供了泛型的通配符"? ","? "可以用来代替任何类型,例如使用通配符来实现print方法。 publicstaticvoidprint(GenList >list){} 泛型的一些局限型 (1)类型参数不能实例化,例如, Tt=newT();//编译错误 (2)不能实例化类型参数的数组 T[]ts=newT[10];//编译错误 (3)类的静态变量不能声明为类型参数类型 publicclassGenClass privatestaticTt;//编译错误 } (4)泛型类不能继承自Throwable以及其子类 publicGenExpection 泛型小结 泛型是J2SE5.0所提供的一项强大的功能,使用泛型可以创建类型安全的、可重用的代码,虽然目前Java的泛型还无法和C++的泛型相提并论,但是,随着Java语言本事的演进,泛型会在Java语言中发挥更大的作用的. Java语言支持在两个类型之间的强制转换,因为每个类即是一个新的类型。 Java支持类类型之间的强制转换,如果B是A的子类,那么B的一个实例亦可作为A的实例来使用,虽然不需要显式的转换,但显式转换亦是合法的,这被称作拓宽(widening)。 如果A的一个实例,想当作B的实例使用,程序员就应写一个类型转换叫作削窄(narrowing)的强制。 从一个类到其子类的强制转换在运行时要作例行的检查以确保这个对象就是其子类的一个实例(或其子类之一)。 兄弟类之间的强制类型转换是一个编译错误,类的强制转换的语法如下? nbsp; ? nbsp; (classname)ref 其中,(classname)是要转换的目的类,而ref是被转换的对象。 强制转换仅仅影响到对象的引用,而不会影响对象本身。 然而,对实例变量的访问却受到对象引用的类型的影响。 一个对象从一个类型到另一类型的强制转换后,可以使同一变量名对不同的实例变量访问。 classClassA{ Stringname="ClassA" } classClassBextendsClassA{//ClassB是ClassA的子类 Stringname="ClassB"; } classAccessTest{ voidtest(){ ClassBb=newClassB(); println(b.name);//打印: ClassB ClassAa a=(ClassA)b; println(a.name);//打印: ClassA } } 数组细节 我们所定义的数组都是Object类的一个子类的实例,在类的层次结构中有一个被称为Array的子类,它有一个实例变量“length”。 对每一个基本类型,都有一个相应的Array的子类。 同理,每一个类也都有一个相应的Array子类存在。 例如: new Thread[n] 创建一个Thread[ ]的实例。 如果类A是类B的超类,那么,A[]是B[]的超类,见下图: Object Array A int[] float[] A[] B B[] 因此,可以把数组赋给一个Object变量。 Object o; int a[]=new int [10]; o=a; 并且可通过强制类型转换把object变量赋给一数组变量。 a=(int [])o; Array类本身不能显式地产生子类。 指向基类的指针访问子类的同名函数,一种方法是把基类的同名函数声明为虚函数。 还有还有一种办法我不确定,请各位高手指教! 就是把基类指针强制转换成子类类型,然后用转换后的指针调用同名函数,我在vc++环境中运行,结果发现调用的是子类的函数。 classclass1 { public: intfun() {return100; } }; classsubclass1: publicclsss1 { public: intfun() {return200; } }; intmain() {class1*p; p=newsubclass1(); intx; x=((sunclsss1*)p)->fun(); printf("%d\n",x);//结果是200 } WatchHilariousVideos FunniestVideosonTheWeb! WatchNow! YourAdHere healer_kx发表于2006-3-1711: 25: 46 你写出这个事实干吗啊? nnlucky发表于2006-3-1711: 28: 20 ? ? 事实? wohow发表于2006-3-1711: 28: 29 这是静态联编,可以这样用,前提是强制转换是正确的就行了 du51发表于2006-3-1711: 29: 09 把基类指针强制转换成子类类型 p=newsubclass1(); x=((sunclsss1*)p)->fun(); nnlucky发表于2006-3-1711: 30: 27 这也是应该是实现父类指针访问子类同名函数的办法吧 pyrophile发表于2006-3-1711: 38: 10 就是呀,这样做没有什么错。 nnlucky发表于2006-3-1711: 41: 33 谢谢了! 对于这个强制转换后的指针,此时只能访问子类新增的public成员吗? pyrophile发表于2006-3-1711: 47: 36 访问不了子类特有的函数。 nnlucky发表于2006-3-1711: 55: 58 嗯? 可以吧,强制转换后可以当成子类的指针使用,这种情况下按理说应该可以访问子类用public声明的函数,如: classclass1 { public: intfun() {return100; } }; classsubclass1: publicclsss1 { public: intfun() {return200; } intfunnew() { return566; } }; intmain() {class1*p; p=newsubclass1(); intx; x=((sunclsss1*)p)->fun(); x=((sunclsss1*)p)->funnew(); printf("%d\n",x); } pyrophile发表于2006-3-1717: 06: 18 x=((sunclass1*)p)->funnew();//那是指向子类的指针当然可以访问了。 adintr发表于2006-3-1717: 12: 50 这不应该叫办法, 应该叫拙略的设计 nnlucky发表于2006-3-1717: 19: 47 adintr给点鼓励嘛,别那么刻薄 hyallentong发表于2006-3-1717: 28: 03 ms用reinterpret_cast<>稍好一点 Jinhao发表于2006-3-1717: 59: 34 如果是多重继承呢
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 泛型