- 什么是泛型?
泛型主要是 Java SE 1.5 的新特性,泛型的本质就是参数化类型,什么是参数化类型呢?就是所操作的数据类型被指定为一个参数,这种参数可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
在编译阶段,识别的是<T>,在运行期识别的是Object类
- 泛型的意义?
a.可以对类型进行自动检查 注:不是替换 仅仅是用来进行类型安全检查!!
b.自动对类型进行类型转换
- 泛型相关定义
1.泛型类
用于封装非特定数据类型的操作,操作执行的大体相同,与所存储的数据类型无关。
和其他普通类定义一样,只是在类后面加上<T>或者<E>
示例
class FanXing <T extends Number> {
private T number;
public FanXing(T number) { this.number = number; }
public void showType(){
System.out.println("T的实际类型是"+number.getClass().getName());
}
class TestDemo{
public static void main(String[] args) {
FanXing<Integer>fa=new FanXing<Integer>(1);
fa.showType();
}
}
2.泛型方法
包含泛型方法的类,可以是泛型类也可以不是,没有干系。
方法中,通过 指定类型参数,可以声明泛型方法,从而提高其可复用性。
泛型方法的参数化类型列表放在方法类符的后面返 回值之前
示例
public<E> void swap(E A,E B){
System.out.println("交换器 a是"+A+" "+"b是"+B);
E TEMP;
TEMP = A;
A = B;
B =TEMP;
System.out.println("交换后 a是"+A+" "+"b是"+B);
}
注:1 如果泛型方法的泛型参数与类型的泛型参数相同,编译器生成警告,因为方法的泛型参数隐藏 了外部类型的泛型参数
2 直接可以通过”方法名()”的形式进行泛型方法的调用,编译器根据传入的方法实参推衍出类型形参。
这好像有点问题或者我理解不对,我将泛型方法写在包含main方法的类中,静态方法就可以直接方法名调用,要是不在则用不了。非静态方法还是得用变量调用
3 使用约束对泛型类型参数起到约束的作用。下面讲
3.泛型接口
泛型接口的声明语法和一般接口的声明语法一致,但需要在声明泛型的接口名称 后加“<>”指定一个或者多个类型参数
示例
interface MyFa<T>{
void add(T a);
}
public class FanXing<T>implements MaFa<T>{
........'
@override
public voi add(T a){
......
}
}
4泛型中一些常见错误
1不能直接 new 泛型数组
若是基本数据类型,则可以定义其包装类型的数组,当做相应的泛型数组使用
示例
public static <E extends Comparable<E> > void swap(E A[],int i, int j){
E temp;
if(A[i].compareTo(A[j])>0){
temp =A[i];
A[i]=A[j];
A[j]=temp;
}
}
FanXing<String>fa=new FanXing<String>("1");
Integer arr[]=new Integer[2];
arr[0]=3;//这个数组,对应wap方法中的参数:E A[]的数组
arr[1]=2;
FanXing.swap(arr,0,1);
2 不能定义泛型对象的数组
3 不能产生泛型类型对象
4 在 static 方法中,是不能用泛型类型参数的。因为 static 方法是不依赖对象存在的,所以无法推知 static 泛型参数类型。
5 泛型参数类型不能是基本数据类型引用数据类型。
5..泛型参数的约束
默认情况下,没有约束条件的泛型类型参数(Sample)T 称为未绑定类型参数,当创建未绑定类型参
数的泛型类实例时,可以给参数类型指定任意类型。想要让泛型参数支持特定类型时,可以使用关键字
extends 或者 super 关键字对泛型参数进行约束。
(1) extends 主要限定泛型参数的上界(常见的使用如下):
<T extends 基类> ://T 只能是基类或者基类的派生类 ;
<T extends 基接口> //T 只能是实现基接口的派生类