java-泛型-详解

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

泛型(Generics)强类型集合类泛型类泛型通配符泛型方法继承中的泛型泛型接口和枚举类型去除集合类中的数据类型n集合类中可以存储各种数据,数据一旦存入,其类型均会转化为Object类型。n从集合类中取出数据时,一般均需要将Object类型转换回存入之前的实际类型Vectorv=newVector();v.add(张三);//存入字符串Stringname=(String)v.get(0);//强制类型转换,OKv.add(newDate());//存入当前时间对象,OK/*由于Date类型不能转换为String,下面语句会在运行时发生错误,但这种错误在编译时不会被检查出来*/Stringdate=(String)v.get(1);//编译器不会发现这里有问题强类型集合n传统的集合类的实例中可以存储任意类型数据,这种集合类称为弱类型集合类。nJDK1.5以后,引入了强类型集合类强类型集合类中,只能存储指定类型的数据在强类型集合类中取出数据时,无需进行类型转换处理,如果数据类型不配备,编译时会直接报错强类型集合并没有引入新的类名,只需在定义原有集合对象时,用尖括号()指明其存储的数据类型名称即可。强类型集合示例//下面的向量类的实例中只能存储字符串类型数据VectorStringv=newVectorString();v.add(张三);//加入的是字符串,OKStringname=v.get(0);//取出时,无需做类型转换/*如果想在这种强类型集合中加入日期数据,在编译时就会报告错误*/v.add(newDate());//编译器会直接报告类型不匹配错误定义泛型(Generics)类n强类型集合采用了JDK1.5引入的泛型语法。n泛型相当于类中一种特殊的类型,这种类型的特点是在实例化该类时可指定为某个具体的实际类型。n声明包含泛型的类的格式如下:[访问修饰符]class类名泛型1,泛型2,…{泛型1泛型成员1;泛型2泛型成员2;//....}n声明中的泛型1、泛型2等等泛型符号可以是任意合法的Java标识符。泛型类的声明示例/*此处声明了一个包含泛型T的泛型类,T代表所有可能的类型,而T的实际类型在Generic类实例化时指定。*/publicclassGenericT{privateTf;//f为泛型成员publicvoidsetF(Tf){//setF方法的参数类型为泛型Tthis.f=f;}publicTgetF(){//getF方法的返回类型为泛型Treturnf;}}//f1中的泛型T在此指定为Boolean类型GenericBooleanf1=newGenericBoolean();//f2中的泛型T在此指定为Integer类型GenericIntegerf2=newGenericInteger();//f1的setF方法只能接受Boolean类型数据f1.setF(newBoolean(true));Booleanb=f1.getF();System.out.println(b);//f2的setF方法只能接受Integer类型的数据f2.setF(newInteger(10));Integeri=f2.getF();System.out.println(i);泛型类的实例化n创建泛型类的实例时,可以使用一对尖括号指定泛型的真正类型n泛型类实例化时,并不一定要指明泛型对应的实际类型,此时会使用Object作为泛型的默认类型n编译时编译器会发出警告:Genericf3=newGeneric();f3.setF(newBoolean(false));Note:Generic.javausesuncheckedorunsafeoperations.Note:Recompilewith-Xlint:uncheckedfordetails.实例化时的泛型的默认类型建立类型为泛型类的数组n如果要建立泛型类的数组,需要注意new关键字后面不要加入泛型的实际类型名,如下所示:GenericString[]gs;//声明泛型类的数组//先对泛型数组进行初始化gs=newGeneric[5];//不要写成newGenericString[5]//再分别为每一个数组元素进行初始化gs[0]=newGenericString();//为第一个数组元素赋值//....publicclassGeneric2T1,T2{privateT1f1;privateT2f2;//....}//给出泛型T1,T2的实际类型GenericInteger,Booleanf=newGenericInteger,Boolean();//没有给出T1,T2的实际类型Genericf1=newGeneric();//T1,T2将被默认为是Object类型包含多个泛型的类定义示例n包含有两个泛型定义的类声明和实例化:publicclassGeneric3T{privateT[]array;//此处不能用newT[]实例化arraypublicvoidsetArray(T[]array){this.array=array;}publicT[]getArray(){returnarray;}}泛型成员的使用n在泛型类中的泛型成员不能直接实例化,其实例必须要通过方法的参数传递给泛型成员:泛型成员实例化示例n通过方法的泛型参数,将数组的实例传递给类中的泛型数组:String[]strs={caterpillar,momor,bush};Generic3Stringf=newGeneric3String();//向泛型成员array传递实际的字符串数组f.setArray(strs);//读取泛型成员array的值,将其赋给字符串数组变量strsstrs=f.getArray();//此时array的类型为字符串数组泛型成员的可用方法n由于泛型类型只有在类实例化后才能确定,类中的泛型成员只能使用Object类型中的方法:classGenericT{Tf;voidsetF(Tf){this.f=f;}//....voiddoSome(){/*getClass和toString都是Object中的方法*/System.out.println(f.getClass().getName());System.out.println(f.toString());}}nextends关键字用来指定泛型的上限,在实例化泛型类时,为该泛型指定的实际类型必须是指定类的子类或指定接口的子接口n在限定泛型的类型时,无论要限定的是接口或是类,都要使用extends关键词importjava.util.List;publicclassListGenericTextendsList{privateTlist;publicvoidsetList(Tlist){this.list=list;}publicTgetList(){returnlist;}}限制泛型上限类型ListGenericVectorf1=newListGenericVector();ListGenericArrayListf2=newListGenericArrayList();限制泛型上限类型的示例//如果不是List的类型,编译时就会发生错误ListGenericHashMapf3=newListGenericHashMap();typeparameterjava.util.HashMapisnotwithinitsboundListGenericHashMapf3=newListGenericHashMap();publicclassGenericT{//....}publicclassGenericTextendsObject{//....}默认的泛型限制类型n定义泛型类别时,如果只写以下代码:n相当于下面的定义方式限定泛型上限后的成员可用方法n泛型类型的上限一经限定,类中的泛型成员就可使用上限类型中的方法和其他可用成员:importjava.util.List;importstaticjava.lang.System.out;//静态导入publicclassListGenericTextendsList{privateTlist;publicvoidsetList(Tlist){this.list=list;}publicvoiddoSome(){//add、get方法都是List接口中定义的方法list.add(newInteger(0));out.println(list.get(0));//此处省略了System}}GenericBooleanf1=newGenericBoolean();GenericIntegerf2=newGenericInteger();f1=f2;//发生编译错误incompatibletypesfound:Genericjava.lang.Integerrequired:Genericjava.lang.Booleanf1=f2;泛型类实例之间的赋值n同一泛型类,如果实例化时给定的实际类型不同,则这些实例的类型是不兼容的,不能相互赋值。泛型中的Object类型兼容性nObject是所有类的父类,因此,所有的类型的实例都可赋值给声明为Object类型的变量n在实例化泛型类时,将泛型指定为Object类型却不存在着和其他类型之间的兼容性:GenericBooleanf1=newGenericBoolean();GenericIntegerf2=newGenericInteger();GenericObjectf=f1;//f1和f类型并不兼容,发生编译错误f=f2;//f2和f类型同样不兼容,也会发生编译错误Booleanf1=newBoolean(true);Integerf2=newInteger(1);Objectf=f1;//OKf=f2;//OK泛型通配字符(Wildcard)n泛型类实例之间的不兼容性会带来使用的不便。n使用泛型通配符(?)声明泛型类的变量可以解决这个问题GenericBooleanf1=newGenericBoolean();GenericIntegerf2=newGenericInteger();GenericObjectf3=newGenericObject();//f可代表Generic所有可能的实例Generic?f;f=f1;//OKf=f2;//OKf=f3;//OK通配符用作方法的参数classUtil{//Collection?可以匹配任何强类型集合staticvoidprintCollection(Collection?c){for(Objecto:c)System.out.println(o);}}n通配符也可以用于方法的参数类型的声明,表示该参数可接受对应泛型类型的任意实例。n以下类定义中的printCollection方法可以打印任意强类型集合中的内容Generic?extendsListf=null;f=newGenericArrayList();//Ok.....f=newGenericVector();//OK....//以下语句会发生编译错误,因为HashMap没有实现List接口f=newGenricHashMap();为通配符指定匹配上限n和限制泛型的上限相似,同样可以使用extends关键字限定通配符匹配类型的上限:incompatibletypesfound:Genericjava.util.HashMaprequired:Generic?extendsjava.util.Listf=newGenericHashMap();//将f限定为只能代表采用java.sq

1 / 38
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功