作用:往常在进行类型转换时,向上转型通常不会出问题,向下转型的时候,虽然编译没问题,运行时可能会出现问题,泛型便可解决这个问题,在本来需要类型转换的地方,无需类型转换,使程序员定义安全的类型。
一、泛型的定义
(1)格式:类名<T> //说明:一般类型用T来表达,容器元素类型用E来表达;另外,T并不代表具体的数据类型,如实例化时不能写成“类名<float>”,而应该指向对应的类,首字母应该大写,应该写成“类名<Float>”
例如:
public class Fan<T> {
privateT over;
publicvoid setOver(T over){
this.over=over;
}
publicT getOver(){
returnover;
}
publicstatic void main(String[] args){
Fan<Float>over1 = new Fan<Float>();
over1.setOver(12.5f);
System.out.println(over1.over);
}
}
(2)泛型可以声明为多个类型,类名<T1,T2>
实例化时,就可以指明多个类型,如:
类名<Foat,Boolean>=new类名<Foat,Boolean>()
(3)定义泛型类之后,可以定义泛型数组
如例子成员变量可定义为:privateT[] over;但是不能直接建立其实例,如private T[] over = new T[10] 就是错误的。
必须先建立相应的泛型对象,在通过setXX(),getXX()方法,为其赋予数组,如:
public class Test2<T> {
public T[] array;
public void setArray(T[] array){
this.array=array;
}
public T[] getArray(){
return array;
}
public static void main(String[] args) {
Test2<String> a = new Test2<String>();
String[] arr={"哈哈","呵呵","嘿嘿"};
a.setArray(arr);
System.out.println(Arrays.toString(a.getArray()));
}
}
输出结果为:[哈哈, 呵呵, 嘿嘿]。
注意其中的代码,泛型数组不能在主方法(静态)中引用,否则报错,而是通过a.getArray()方法,实现对其的调用。
(4)集合框架都已经被泛型化了,无需再建立泛型,可以直接用
常见的被泛型化的集合类:
集合类 | 泛型定义 |
ArrayList | ArrayList<E> |
HashMap | HashMap<K,V> |
HashSet | HashSet<E> |
Vector | Vector<E> |
二、泛型的高级用法
(1)限制泛型可用类型
格式:class 类名称<Textends anyclass> //anyclass指的是任意类
这样便限定了泛型类必须为实现或继承了anyclass的类实例对象。
(2)使用类型通配符
泛型中可以使用通配符“?”,表式任意一个类,结合继承便限定了泛型的类型
格式:
类名<? Extends 父类> //泛型必须为父类的子类
类名<? Superanyclass> //泛型必须为anyclass的父类或anyclass的接口
注意:使用了通配符的泛型只能查询与删除,不能插入新值。
(3)泛型类可以被继承,泛型接口可以被实现
格式:subclass<T1,T2>extends uperclass<T> //父类的泛型一般要保留,否则子类的泛型默认为object,泛型接口同样的道理