泛型:
将原本确定不变的数据类型参数化。
从jdk5.0开始引入,提高java应用程序的类型安全,可维护性,可
扩展性。
为集合提供编译时类型完全检查,创建集合容器时,规定其允许存储的元素类型,然后由编译器负责添加元素的类型合法性检查,再取出集合元素时则不需要进行强制转型。
//集合使用了泛型机制,只能保存指定类型的元素,编译时就安全检查
ArrayList<String> list=new ArrayList<String>();
list.add("hello");
泛型类:
由类型参数修饰的类型称为,泛型类。
格式:类名<类型参数>
类型参数对整个类有效
使用泛型类时,应该明确指定类型参数。
//自定义泛型类,类型参数T,整个类中都可以使用
public class Person<T> {
private String name;
private T secrecy;
}
注意:
同一个泛型类,搭配不同的类型参数复合而成的类型属于同一类,但却是不同的类型
Person<String> p1=new Person<String>();
Person<Integer> p2=new Person<Integer>();
//p1 = p2 错误!
同一个泛型类,与不同的类型参数复合而成的类型间并不存在继承关系,即使类型参数间存在继承关系时,也是如此。
类型
通配符:
提高使用泛型后的通用性。
使用了通配符?的对象,在调用方法时,操作是受限的,
凡是必须知道具体类型参数,才能进行的操作均被禁止。
Demo2 test=new Demo2();
ArrayList<Integer> list2=new ArrayList<Integer>();
ArrayList<String> list1=new ArrayList<String>();
test.display(list1);
System.out.println("========================");
test.display(list2);
//类型通配符?,增强了通用性的安全,操作是受限(不能add,不表示只读)
public void display(ArrayList<?> list){
//list.add("test");//不可以
//list.clear(); //可以操作
list.remove(new Integer(1000));//可以操作
for (Object s:list){
System.out.println(s);
}
}
泛型方法:
在一个方法内,对数据类型进行参数化。
定义语法:[访问修饰符]<类型参数><返回类型><方法名>(形参){}
一个static方法,无法访问泛型类的类型参数,因为类还没有实例化,
所以,若static方法需要使用泛型能力,必须使其成为泛型方法。
//泛型方法
public <T> T evaluate(T a,T b){
if(a.equals(b)){
return a;
}
return null;
}
//自定义泛型类,类型参数T,整个类中都可以使用
//一个static方法,无法访问泛型类的类型参数,因为类还没有实例化
public class Person<T> {
/*
public static void display(T xx){
}
*/
//所以,若static方法需要使用泛型能力,必须使其成为泛型方法。
public static <T> void display(T xx){}
}
受
限制的类型参数:
extends
关键字,受限泛型是指类型参数的取值范围是受到限制的。
类名<T extends 类 |
接口>
兼顾泛型类的通用性,和针对性。
//Serializable是接口,区域性限制。
public class Point<T extends Number & Serializable>{
}
受限制的通配符:
//只能接受 Number 类下的继承类,使取值范围受限制。
ArrayList<? extends Number> list=list1;
//只能接受 Number 类的父类。
public static void display(ArrayList<? super Number> list){
for (Object obj:list){
System.out.println(obj);
}
}