JAVA基础--泛型
一、作用
- 泛化、参数化类型。所操作的数据类型被指定为一个参数;
- 类型安全。编译时验证类型,如果编译时正常,运行时就不会出现
ClassCastException
(类型转换异常) 异常; - 消除强制类型转换。泛型可以消除源代码中的许多强制类型转换,这样可以使代码更加可读,并减少出错的机会。
二、泛型的声明
格式:<T>
标识符一般使用单个大写字母,常用 T ,含有Type的意思;
包含多个参数类型时,可以用逗号隔开;例如:<K,V>
三、泛型类
定义:
class 类名 <T,R...>{
}
- 类中的普通成员、方法可以使用类的泛型;
- 静态成员、方法无法使用类的泛型。因为类加载时,对象还未初始化,无法确定泛型的具体类型;
- 泛型类的类型在对象初始化时确定;
- 对象初始化时未指定类型,默认类型为Object;
例:
public class GenericsTest<T> {
private T member;
// 该方法为普通方法,这里的 T 为返回值类型,具体的数据类型在对象创建的时候定义
public T getValue(List<T> a){
return a.get(0);
}
}
四、泛型接口
定义:
interface 接口名 <T,R......>{
}
- 泛型接口类的泛型类型,在继承接口或实现接口时确定
- 其他特性与泛型类相同
interface GenericsTest<T> {
T value;
// 该方法为普通方法,这里的 T 为返回值类型,具体的数据类型在对象创建的时候定义
T getValue();
}
// 继承
interface StingTest extends GenericsTest<String>{
}
// 实现
class StringClass implements GenericsTest<String>{
private String value;
@Override
public String getValue(){
return this.value;
}
}
五、泛型方法
修饰符<T,R...> 返回类型 方法名(参数列表) {
}
- 普通类或泛型类中都可以定义泛型方法;
- 当泛型方法调用时类型会被确定;
- 注意区分普通方法和泛型方法的区别,泛型访问有泛型声明
<T>
public class GenericsTest<T> {
// 该方法为普通方法,这里的 T 为返回值类型,具体的数据类型在对象创建的时候定义
public T getValue(List<T> a){
return a.get(0);
}
// 静态属性和静态方法不能直接使用类的泛型作为参数类型,类加载时对象还没定义,无法确定T代表的具体数据类型
// public static T getValue1(List<T> a){
// return a.get(0);
// }
// 该方法声明了<T> , 是泛型方法,即使是静态方法也可以使用
public static <T> T getValue2(T a){
return a;
}
// 方法中使用 非类声明的泛型类型 时,需要另外声明。 如方法:getValue4
// public E getValue3(List<E> a){
// return a.get(0);
// }
// 声明了 方法 返回的泛型<E>
public static <E> E getValue4(List<E> a){
return a.get(0);
}
}
六、类型通配符 "?"
-
<?>
:支持任意泛型类型 -
<? extends A>
:支持A类以及A类的子类,规定了泛型的上限 -
<? super A>
:支持A类以及A类的父类,不限于直接父类,规定了泛型的下限