Java泛型基础

来源:互联网 发布:国服mac版魔兽世界 编辑:程序博客网 时间:2024/05/25 16:38

1、出现原因:编译时不会进行类型检查

例:

List strList = new ArrayList();

strList.add("Hello world");

strList.add("Hello China");

//这里不小心把int型5add进去了。

strList.add(5);

strList.forEach(str->System.out.println(((String)str).length()));//这里就会报ClassCastException


2、泛型使用

继续使用上面例子:

List<String> strList = new ArrayList<String>();

strList.add("Hello world");

strList.add("Hello China");

//这里不小心把int型5add进去了,但会引起编译错误。

strList.add(5);

strList.forEach(str->System.out.println(((String)str).length()));//这里就会报ClassCastException


3、泛型语法

例:Java7之前创建对象时构造器后面也必须带泛型,Java7之后可省略

List<String> strList = new ArrayList<String>();

Map<String,Integer> scores = new HashMap<String,Integer>();

--------------------------------Java7分割线-----------------------------------------

List<String> strList = new ArrayList<>();

Map<String,Integer> scores = new HashMap<>();


4、深入泛型

例:可以生成多个逻辑子类(物理上并不存在,仍然是Apple,不是什么AppleString或Appler<String>对象)

public class Apple<T>{


private T info;

public Apple(T info){

this.info = info;

}

public void setInfo(T info){

this.info = info;

}

public T getInfo(){

return this.getInfo;

}


public static void main(String[] args){

//传一个String类型的苹果

Apple<String> a1 = new Apple<String>("苹果");

System.out.println(a1.getInfo());


//传一个Double类型的Apple

Apple<Double> a2 = new Apple<Double>(5.66);

System.out.println(a2.getInfo());

}


}


5、泛型类派生子类

使用Apple例子:

public class A extends Apple<T>{}//错误,Apple类不能跟类型形参T

public class A extends Apple<String>{}//正确,给Apple类传String实参

public class A extends Apple<>{}//正确,给Apple类传Object实参,但Java编译器会有Warnning


6、类型通配符

例:使用“?”表示可以匹配任何类型。

public void test(List<?> c){

for(int i = 0;i<c.size();i++){

System.out.println(c.get(i));

}

}


7、被限制的泛型通配符

例:

有Shape抽象类

Circle类继承Shape

Rectangel类继承Shape


使用Canvas画多个形状时:

public class Canvas{

public void drawAll(List<Shape> shapes){

for(Shape s:shages){

s.draw(this);

}

}

}

调用地方:

List<Circle> circlList = new ArrayList<>();

Canvas c = new Canvas();

c.drawAll(circlList);//这里会编译错误,因为List<Circle>不是List<Shape>的子类


解决方案1:使用?通配符,然后再转成Shape类,最后调用draw方法。

public class Canvas{

public void drawAll(List<?> shapes){

for(Object obj:shages){

Shape s = (Shape)obj;

s.draw(this);

}

}

}


解决方案2:使用被限制的通配符List<? extends Shape>

public class Canvas{

public void drawAll(List<? extends Shape> shapes){

for(Shape s:shages){

s.draw(this);

}

}

}


8、被限制的类型形参

不仅仅可以这么玩(使用被限制的通配符):List<? extends Shape>

还可以这么玩(使用被限制的类型形参):Apple<T extends Number>

public class Apple<T extends Number>{


private T info;


public static void main(String[] args){

//传一个Integer类型的苹果,可以,因为它是Number子类

Apple<Integer> a1 = new Apple<>();

//传一个Double类型的苹果,可以,因为它是Number子类

Apple<Double> a2 = new Apple<>();

//传一个String类型的苹果,这就不行了,因为它不是Number子类,所以编译错误。

Apple<String> a3 = new Apple<String>();

}


}


9、泛型方法

例:

static <T>void fromCollectionToCollection(Collection<T> from,Collection<T> to){

for(T o:from){

 to.add(o);

}

}

使用时不能制造迷惑,让编译器能准确推断出泛型方法中类型形参的类型。

such as:

Collection<Object>from= new ArrayList<>();

Collection<Object> to= new ArrayList<>();

fromCollectionToCollection(from,to);


not do that:

Collection<Object>from= new ArrayList<>();

Collection<String> to= new ArrayList<>();

fromCollectionToCollection(from,to);

Object不是String类型,也不是String类型的子类,所以编译报错。不可以使用?解决not do that 案例-》

解决方案:

static <T>void fromCollectionToCollection(Collection<? extends T> from,Collection<T> to){

for(T o:from){

 to.add(o);

}

}


10....






原创粉丝点击