1. 泛型类是有一个或者多个参数的类,被用作实例变量的类型,方法的参数类型,返回值的类型
tips:类型参数不能用基本类型实例化
public class Entry <K, V> {
private K key;
private V value;
public Entry(K key , V value){
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
}
构造泛型类的对象, 钻石语法中的类型是被推测出来的
public static void main(String[] args) {
Entry<Integer, String> example = new Entry<>(23, "broccoli");
}
2. 泛型方法,泛型方法是带参数类型的方法,可以是普通类或者是泛型类的方法
声明一个泛型方法的时候,类型参数要放在修饰符(如 public或者static)之后,返回类型之前
public static <T> void swap(T[] array, int i , int j){
//logic code
}
3. 类型限定, 泛型类或者方法的类型参数需要满足某些要求
<T extends AutoCloseable> 限定 元素类型是 AutoCloseable 的子类型, 可以有多个限定 通过 & 并操作符,这里区别异常使用多个 或 连接的,然后 限定只能有一个是类,接口可以多个,如果有一个限定是类必须放在限定列表的第一位
public static <T extends AutoCloseable & Runnable> void TaAge(Employee[] array){
}
public static <T extends AutoCloseable & Runnable> void TaAge2(ArrayList<Employee> list){
}
//报错因为只能 extends 一个类,但是可以extends 多个接口
public static <T extends Employee & Manager> void TaAge3(Employee[] array){
}
//通配符号,对于统配符号的对象,你只能进行读取,不能进行写数据
public static <T extends AutoCloseable & Runnable> void TaAge3(ArrayList<? extends Employee> list){
}
//通配符号,传递父类型
public static <T extends AutoCloseable & Runnable> void TaAge4(ArrayList<? super Employee> list){
}
4. 变异类型和通配符
协变性
//假如manager类是子类,那么在这里传入 Manager[]对象也可以
public static void process(Employee[] stuff){
}
//但是ArrayList<Manager>不是ArrayList<Employee>的子类型
ArrayList<Manager> managers = new ArrayList<>();
//非法
ArrayList<Employee> employees = managers;
子类型通配符:为什么这么设计,如果一个方法不对数组列表进行写操作,不会损坏数组列表
可以将 ? extends Employee 转换成 Employee,但是不能讲任何对象转换成 ? extends Employee, 所以你可以从 ArrayList<? extends Employee> arrayList中读数据而不能写数据
public static void printNames(ArrayList<? extends Employee> arrayList){
for (int i = 0; i< arrayList.size(); i++){
// get方法会返回一个 ? extends Employee 的对象,?表示 Employee的子类型
Employee e = arrayList.get(i);
System.out.println(e.getName());
}
//这个方法没办法执行,因为 ? 可以是任何子类
arrayList.add();
}
父类型通配符: ? super Employee 代表了 Employee 的一个父类型,当给方法指定一个泛型函数式接口的参数时,一般使用super
生产者读取数据,使用extends , 消费者 使用 super
带类型变量的通配符
public static <T> void testList(T[] elements, Predicate<? super T> filter){
}
无限定通配符: ?
public static boolean hasNulls(ArrayList<?> list){
for (Object o : list) {
if(o == null) {
return true;
}
}
return false;
}
通配符捕获:可以将 ? 当做一个类型的参数,但是不能用作为一个类型
记住一点,所有有关泛型的接口都是不变的

网友评论