1) 泛型是一种可变化的类型
类型不确定,需要调用者来指定
2) 用途:
一个类的多个成员方法用到的参数类型或返回值类型都是未知的类型,但又需要是同一个类型,就可将方法的
参数类型定义为泛型,此泛型必须在类上先予以声明才能在方法中使用
一个方法的多个参数和返回值需要是同一个类型,也可以用泛型来解决,在方法返回值前面声明泛型
泛型的细节:
1) 泛型到底代表什么类型取决于调用者传入的类型,如果没传,默认是Object类型
2) 使用带泛型的类创建对象时, 等式两边指定的泛型必须一致
原因: 编译器检查对象调用方法时只看变量,然而程序运行期间调用方法时就要考虑对象具体类型了
3) 等式两边可以在任意一边使用泛型 在另一边不使用 (考虑向后兼容)
3. 泛型的基本概念
以List<E>为例:<>念着typeof 例, List<String> 就是 List typeof String
List<E>中的E称为类型参数变量 方法定义参数形式参数
List<Integer>中的Integer称为实际类型参数
整个List<E>称为泛型类型 GenericType
整个List<Integer>称为参数化的泛型类型
4. 泛型的使用
1)使用带泛型的类时,在创建对象时可以为泛型指定实际类型参数,指定的具体类型相当于给泛型传参
2)子类在继承父类的时候,可以为父类定义的泛型指定实际类型参数
class B<T>
class A extends B<String>
通过子类A获得的父类类型就是一个参数化的类型
3)调用方法时传入参数的具体类型将作为方法中泛型的实际类型
1. 为什么使用泛型?
在jdk5以前,对象一旦存入集合就是去特性,变成Object类型
从集合取出元素时,就需要做强转,
有的时候我们不确定集合中到底存储的是什么类型,强转时容易出错
在jdk5中,为了提供集合的安全性,定义了泛型,我们可以在使用集合时利用泛型
限定集合存入的数据类型
2. 用泛型的好处?
在迭代集合时,可以避免强转的麻烦
将运行时期的错误转移到编译阶段
3. 由于集合是用于存储对象的,基本数据类型需要包装后才能存入集合,所以
集合上使用的泛型必须是引用数据类型
4. 什么情况下用泛型
如果一个类有两个或多个方法的形参必须为同一种类型,或者方法的返回值必须为同一种类型
就可以使用泛型来解决
简单来说,在一个类中多个方法使用的类型必须是同一种类型,但是可以为任意类型
5. List<T> 当中T称为类型参数 List<String> 当中String 实际类型参数
6. 自定义泛型
在类的后面自定义泛型,类型多处用到的类型需要是同一种类型
// 一个学生对象学习什么就必须玩什么
public class Student<T,E> {
// 使用类型参数
public T study(T t) {
return null;
}
public void play(T t) {
}
public void eat(E e) {
}
}
定义泛型方法, 方法的形参和返回值需要是同一种类型
// 求两个数的最大数
// 判断两个对象中的较大者
public static <T> T getMax(T x, T y) {
/*if(x>y)
return x;
return y;*/
// TreeSet
// 判断x对象是否具备比较的功能
if(x instanceof Comparable) {
Comparable com = (Comparable) x;
int num = com.compareTo(y);
if(num>0)
return x;
return y;
}
// 说明x不具备比较功能
throw new RuntimeException("对不起,比不了!");
}
public static <T> void reverse(T[] arr) {
int start = 0;
int end = arr.length - 1;
while(end>start) {
T temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}