《core JAVA for the impatient》阅读笔记(5) 泛型编程

泛型方法

类型参数要放在修饰符之后,返回类型之前

public static <T> void swap(T[] array,int i,int j)

调用时:

String[] friends = ...;
Arrays.swap(friends,0,1)

编译器可以推断T应是String类型

类型限定

public static <T extends AutoCloseable> void closeAll(ArrayList<T> elems) throws Exception{
	for(T elem:elems) 
		elem.close();
}

类型变异和通配符

  • 协变性
    可以将 Manager[] 数组传递给参数为 Employee[] 的方法
    因Manager[]是 Employee[] 的子类型

但是,ArrayList<Manager>不是ArrayList<Employee>的子类型
这时不允许转换

  • 子类型通配符
    public static void printNames(ArrayList<? extends Employee> staff)

"?"表示一个未知的Employee子类型

可以给这个方法传递一个Employee类型或者它的子类组成的数组列表

这种方法只能读不能写,因为可以将未知的传入类型转换成Employee类型,但不能将任何对象转换为一个未知的<?extends Employee>

  • 父类型通配符
    ? super Employee代表任意一个Employee的父类类型(包括Object)
    这种通配符经常用作函数式参数
    Predicate<T>接口有一个方法,用于测试T类型的对象是否有特定的属性
public interface Predicate<T>{
	boolean test(T arg);
	...
}
public static void printAll(Employee[] staff,Predicate<? super Employee> filter){
	for(Employee e:staff)
		if(filter.test(e))
			System.out.println(e.getName());
}
  • 带类型变量的通配符

3个例子:

  1. public static <T> void printAll(T[] elements,Predicate<? super T> filter)
  2. public void addAll(Collection<? extends E> c)
  3. public static <T extends Comparable<? super T>> void sort(List<T> list)
  • 无限定通配符和通配符捕获
import java.util.ArrayList;



public class 枚举类型 {
	public static void swap(ArrayList<?> elements,int i,int j){
		swapHelper(elements,i,j);
	}
	private static <T> void swapHelper(ArrayList<T> elements,int i,int j){
		T temp=elements.get(i);
		elements.set(i,elements.get(j));
		elements.set(j,temp);
	}
	public static void main(String[] args) {

	ArrayList<String> ele=new ArrayList<>();
	ele.add("dasd");
	ele.add("daaaa");
	swap(ele,0,1);
	System.out.println(ele);
	}
}

输出结果:[daaaa,dasd]

猜你喜欢

转载自blog.csdn.net/m0_37753327/article/details/83043333