邯郸软件开发|邯郸软件定制|邯郸APP开发|邯郸APP定制|邯郸手机应用开发|邯郸微信|邯郸网络公司|邯郸软件公司|邯郸行业软件|邯郸金融软件|邯郸停车场系统


邯郸市锦诚网络科技有限公司

示例图片三
网站首页 > 新闻资讯 > 业界资讯

泛型的意义和作用是啥?

2017-06-14 09:06:51 邯郸市锦诚网络科技有限公司 阅读

意义和作用有:

简单的说。

类型的参数化,就是可以把类型像方法的参数那样传送。这一点意义非凡。

泛型使编译器可以在编译期间对类型进行检查以提高类型平安,减少运行时由于对象类型不匹配引发的异常。

泛型方法,算法的复用。蛮神奇的

邯郸市锦诚网络科技有限公司--IT信息化全程服务专家

想要理解为什么引入泛型,就要知道没有泛型的麻烦。

知道现在顺序开发都是面向对象了所以顺序里会有很多各种类型的对象,对象多了肯定需要有某种类型的容器来装。所以就有了一些容器类型,比如数组、ArrayListHashMapTreeSet等。

对于数组,知道需要在使用时指定数组装的对象类型,如:


1

2

3


A nimanimal[];

 

Dogdog[];





而对于集合类型容器如ArrayListHashMapTreeSet等,不但是容器,还提供了一些方法对容器内对象的操作方法,如getsetsort这个时候就需要知道容器内放的什么类型的对象,才干return或set

正因为顺序开发人员可能把任何类型的对象放进集合容器,所以这些容器在设计的时候只能默认设计成装Object类型对象。因为Java里Object根类。

所以容器就成了类似这个样子:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17


publicclassListContain{

 

privateObjectobj;

 

publicObjectgetObj{

 

returnobj;

 

}

 

publicvoidsetObjObjectobj{

 

this.obj=obj;

 

}

 

}





这样的话,根据多态,容器就能装任何类型的对象了不过,取出对象时则需求进行强制类型转换,转换成实际的类型。但这样会有很多类型不安全问题,为什么呢?因为编译器没法协助做类型检查,导致代码在运行时易于出现ClassCastExcept异常。因此,类型平安问题只能由顺序员自己来把关了记住各种类型,防止类型转换错误。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15


ListContainmyContain=newListContain;

 

myContainer.setObj"123";

 

A rrayListobjectList=newA rrayList;

 

objectList.addmyContain;

 

//下面这句编译时无异常,运行时会ClassCastExcept异常

 

IntegmyStr=IntegerListContainobjectList.get0.getObj;

 

//下面这句ok

 

StrmyStr=StringListContainobjectList.get0.getObj;





泛型出场:类型的参数化

利用泛型,重新设计:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17


publicclassListContainer<T>{

 

privateTt;

 

publicTgetObj{

 

returnt;

 

}

 

publicvoidsetObjTt{

 

this.t=t;

 

}

 

}





这里<T>T类型的参数,具体T指代什么类型,String还是Animal还是Dog类型此处不论,而在顺序员开发时使用到ListContain时再指定,如:


1


ListContainer<Dog>myCon=newListContainer<Dog>;





这种环境下,编译器就知道ListContain容器是放Dog类型对象的并进行类型平安检查。


1

2

3


myCon.setObjnewDog//ok

 

myCon.setObj123;//编译时提醒类型错误





这样设计的容器在使用时编译器就可以协助做很大一部分的类型平安检查工作了这就避免了很多运行时的ClassCastExcept异常,顺序员也无需记住各种对象的类型和担心类型匹配问题了同时大部分情况下也不用做类型强制转换工作了


1

2

3

4

5

6

7

8

9

10

11

12

13


ListContainer<String>myContain=newListContainer<String>;

 

myContainer.setObj"123";

 

myContainer.setObjnewDog;//编译器就提醒类型异常

 

A rrayListobjectList<ListContainer>=newA rrayList<ListContainer>;

 

objectList.addmyContain;

 

IntegmyStr=objectList.get0.getObj;//编译时提醒类型异常

 

StrmyStr=objectList.get0.getObj;





当然泛型的<>里也可以放多个参数,如:


1

2

3

4

5

6

7

8

9


publicclassMultiContainer<T,S>{

 

privateTt;

 

privateSs;

 

...

 

MultiContainer<String,Dog>multicon=newMultiContainer<String,Dog>;





有界泛型

看看这个泛型和多态的问题,Dog,CatAnimal子类:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19


publicvoidkillA lArrayList<A nimal>anim{...};//A nim容器

 

...

 

A rrayList<A nimal>animals=newA rrayList<A nimal>;

 

animals.addnewDog;

 

animals.addnewCat;

 

killA lanim;//这里ok

 

A rrayList<Dog>dogs=newA rrayList<Dog>;//DogAnimal子类

 

dogs.addnewDog;

 

dogs.addnewDog;

 

killA ldog;//这里编译不通过





这里看上去似乎多态不行了

这里就要用到有界泛型:

使用泛型时,会有这种需求:需要指定泛型的类型范围。有界类型就是类型参数局部指定extend或super关键字,这里的extend也含有implement功能,分别用上限或下限来限制类型范围,从而限制泛型的类型边境。例如:


1

2

3


<TextendsA nimal>//限定TAnimal子类

 

<TsuperDog>//限定TDog超类





那么上面那个多态问题就变成:


1


publicvoidkillA lArrayList<TextendsA nimal>anim{...};





解决了


1


<TextendsObject&Comparable&Serializable>





多个限定时我可以使用&来进行分割,这时关键词只能使用extend与多重继承类似,这里只有一个类其他都是接口。

泛型方法

有时,设计的方法可能其参数类型是不限定的这种场景如果用重载方法的方式来做的话,算法重复,不是最好的方案。此时泛型方法就可以解决此类问题。

如Calculadd方法:


1

2

3

4

5

6

7

8

9


publicstatic<NextendsNumber>doubleaddNa,Nb{

 

doublesum=0;

 

sum=a.doubleValu+b.doubleValu;

 

returnsum;

 

}





如果用重载来做的话,要很多重复代码了


Powered by MetInfo 5.3.14 ©2008-2018 www.metinfo.cn