主页»Java WEB»泛型的含义和效果是啥?

泛型的含义和效果是啥?

来历:hexter 发布时刻:2017-06-03 阅览次数:

  简略的说,含义和效果有:

  类型的参数化,便是能够把类型像办法的参数那样传递。这一点含义特殊。

  泛型使编译器能够在编译期间对类型进行查看以进步类型安全,削减运转时由于目标类型不匹配引发的反常。

  泛型办法,算法的复用。蛮奇特的。

  想要了解为什么引进泛型,就要知道没有泛型的费事。

  咱们知道现在的程序开发都是面向目标了,所以程序里会有许多各种类型的目标,目标多了必定需求有某种类型的容器来装。所以就有了一些容器类型,比方数组、ArrayList、HashMap、TreeSet等。

  关于数组,咱们知道需求在运用时指定数拼装的目标类型,如:

Animal animal[];

Dog dog[];

  而关于调集类型容器如ArrayList、HashMap、TreeSet等,它们不但是容器,还供给了一些办法对容器内目标的操作办法,如get,set,sort。这个时分就需求知道容器内放的是什么类型的目标,才干return或set。

  正由于程序开发人员或许把任何类型的目标放进调集容器,所以这些容器在规划的时分只能默许规划成装Object类型目标。由于Java里Object是根类。

  所以容器就成了相似这个姿态:

public class ListContainer {

private Object obj;

public Object getObj() {

return obj;

}

public void setObj(Object obj) {

this.obj = obj;

}

}

  这样的话,依据多态,容器就能装任何类型的目标了。不过,取出目标时则需求进行强制类型转化,转化成实践的类型。但这样会有许多类型不安全问题,为什么呢?由于编译器无法帮助做类型查看,导致代码在运转时易于呈现ClassCastException反常。因而,类型安全问题只能由程序员自己来把关了,记住各种类型,防止类型转化过错。

ListContainer myContainer = new ListContainer();

myContainer.setObj("123");

ArrayList objectList = new ArrayList();

objectList.add(myContainer);

//下面这句编译时无反常,运转时会ClassCastException反常

Integer myStr = (Integer) ((ListContainer)objectList.get(0)).getObj();

//下面这句ok

String myStr = (String) ((ListContainer)objectList.get(0)).getObj();

  泛型进场:类型的参数化

  运用泛型,从头规划:

public class ListContainer<T> {

private T t;

public T getObj() {

return t;

}

public void setObj(T t) {

this.t= t;

}

}

  这儿<T>的T的类型的参数,具体T指代什么类型,是String仍是Animal仍是Dog类型此处不论,而在程序员开发时运用到ListContainer时再指定,如:

ListContainer<Dog> myCon=new ListContainer<Dog>();

  这种环境下,编译器就知道ListContainer容器是放Dog类型目标的。并进行类型安全查看。

myCon.setObj(new Dog())//ok

myCon.setObj(“123”);//编译时提示类型过错

  这样规划的容器在运用时编译器就能够帮助做很大一部分的类型安全查看作业了,这就防止了许多运转时的ClassCastException反常,程序员也无需记住各种目标的类型和忧虑类型匹配问题了。一起大部分情况下也不用做类型强制转化作业了。

ListContainer<String> myContainer = new ListContainer<String>();

myContainer.setObj("123");

myContainer.setObj(new Dog());//编译器就提示类型反常

ArrayList objectList<ListContainer> = new ArrayList<ListContainer>();

objectList.add(myContainer);

Integer myStr = (objectList.get(0)).getObj(); //编译时提示类型反常

String myStr = (objectList.get(0)).getObj();

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

public class MultiContainer<T,S> {

private T t;

private S s;

...

MultiContainer<String,Dog> multicon=new MultiContainer<String,Dog>();

  有界泛型

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

public void killAll(ArrayList<Animal> animals){...};//Animal容器

...

ArrayList<Animal> animals=new ArrayList<Animal>();

animals.add(new Dog());

animals.add(new Cat());

killAll(animals);//这儿ok

ArrayList<Dog> dogs=new ArrayList<Dog>();//Dog是Animal的子类

dogs.add(new Dog());

dogs.add(new Dog());

killAll(dogs);//这儿编译不经过

  在这儿看上去好像多态不行了。

  这儿就要用到有界泛型:

  在运用泛型时,咱们会有这种需求:需求指定泛型的类型规模。有界类型便是在类型参数部分指定extends或super关键字,这儿的extends也含有implements的功用,别离用上限或下限来约束类型规模,然后约束泛型的类型鸿沟。例如:

<T extends Animal>//限制T是Animal的子类

<T super Dog >//限制T是Dog的超类

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

public void killAll(ArrayList<T extends Animal> animals){...};

  处理了。

<T extends Object&Comparable&Serializable>

  多个限制时咱们能够运用&来进行切割,这时关键词只能运用extends。与多重承继相似,这儿只要一个类其他都是接口。

  泛型办法

  有时,咱们规划的办法或许其参数类型是不限制的。这种场景假如用重载办法的办法来做的话,算法重复,不是最好的计划。此刻泛型办法就能够处理此类问题。

  如Calculator的add办法:

public static <N extends Number> double add(N a, N b){

double sum = 0;

sum = a.doubleValue() + b.doubleValue();

return sum;

}

  假如用重载来做的话,要许多重复代码了。

QQ群:凯发娱乐官网官方群(515171538),验证音讯:10000
微信群:加小编微信 849023636 邀请您参加,验证音讯:10000
提示:更多精彩内容重视微信大众号:全栈开发者中心(fsder-com)
188bet uedbet 威廉希尔 明升 bwin 明升88 bodog bwin 明升m88.com 18luck 188bet unibet unibet Ladbrokes Ladbrokes casino m88明升 明升 明升 m88.com 188bet m88 明陞 uedbet赫塔菲官网 365bet官网 m88 help
网友谈论(共0条谈论) 正在载入谈论......
沉着谈论文明上网,回绝歹意咒骂 宣布谈论 / 共0条谈论
登录会员中心