前言:
有时候我们在看别人代码的时候会看到这样的形式:
List <String>
,却不懂得是什么意思?所以我现在就来说一说这个泛型。
一、泛型的定义
- 泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
<T>: 定义一个泛型的变量, 默认值: Object 在类上定义: 这个类称为泛型类 泛型变量在类的构造方法,非静态方法的参数 非静态方法的返回值使用 属性的数据类型 不能在静态方法上使用
例子:
// 定义一个string参数的list集合 List<String> arrayList = new ArrayList<String>();
- 静态泛型方法, 这个泛型变量需要在静态方法上声明,再使用
public static <E> E 方法名(E 参数名){ } //定义一个参数为integer 和 string的集合 public static Map<Integer,String> mapPoker = new HashMap<>();
二、泛型的使用
1、普通方法
//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时,必须指定T的具体类型public class Generic<T>{ //key这个成员变量的类型为T,T的类型由外部指定 private T key; }
常用的 T,E,K,V,? 本质上这些个都是通配符,没啥区别,只不过是编码时的一种约定俗成的东西。比如上述代码中的 T ,我们可以换成A-Z 之间的任何一个 字母都可以,并不会影响程序的正常运行,但是如果换成其他的字母代替 T,在可读性上可能会弱一些。通常情况下,T,E,K,V,? 是这样约定的:
(1) ? 表示不确定的 java 类型
(2) T (type) 表示具体的一个java类型
(3) K V (key value)分别代表java键值中的Key Value
(4) E (element) 代表Element
2、泛型接口
泛型接口与泛型类的定义及使用基本相同。泛型接口常被用在各种类的生产器中
//定义一个泛型接口
public interface Generator<T> {
public T next();
}
3、 使用其他定义好的泛型类,或者泛型方法
比如: 集合类都是jdk已经定义好的泛型类
4、<E>
: 泛型类型变量
使用: 给泛型类型变量赋值: 在创建这个类的时候,使用
<具体数据类型>
赋值泛型赋值数据类型只能是类类型,不能是基本数据类型
泛型没有继承关系
泛型变量没有赋值: 就是Object
三、泛型通配符
? 任意数据类型
定义一个方法, 接收一个泛型类类型的变量, 不确定泛型类的泛型变量类型, 这个参数不能类
<Object>
,因为泛型没有继承,
使用?通配符使用通配符的泛型变量, 只能只读的
例子:
> static void reverse(List<?> list) //把List集合的元素反转
四、泛型限制
泛型上限:
- 格式:
类型名称<? extends 类> 对象名称
- 意义: 只能接收该类型及其子类
public void showKeyValue1(Generic<? extends Number> obj){ Log.d("泛型测试","key value is " + obj.getKey()); }
泛型下限:
- 格式:
类型名称<? super 类> 对象名称
- 意义:只能接收该类型及其父类类型
private <T> void test(List<? super T> dst, List<T> src){ for (T t : src) { dst.add(t); } } public static void main(String[] args) { List<Dog> dogs = new ArrayList<>(); List<Animal> animals = new ArrayList<>(); new Test3().test(animals,dogs); } // Dog 是 Animal 的子类 class Dog extends Animal { }
五、泛型集合
常用方法:
static <T> boolean addAll(Collection<? super T> c, T... elements) //把数组的元素添加到集合
static void reverse(List<?> list) //把List集合的元素反转
static void shuffle(List<?> list) //随机打乱List集合元素的顺序
static <T extends Comparable<? super T>> void sort(List<T> list) //自然排序
static <T> void sort(List<T> list, Comparator<? super T> c) //指定排序
最后:本文中的例子主要是为了阐述泛型中的一些思想而简单举出的,并不一定有着实际的可用性。其实很多人都以为泛型只是在集合中,但是,在实际的编程过程中,自己可以使用泛型去简化开发,且能很好的保证代码质量。