概念
泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?
顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),
然后在使用/调用时传入具体的类型(类型实参)。
使用
1、泛型类:
public class TaskResult<R> {
private R data;
private String reason;
private ResultEnum result;
}
使用:
TaskResult<Result> result = new TaskResult<>();
2、泛型接口:
//定义一个泛型接口
public interface ITaskProcesser<R, T> {
public TaskResult<R> taskExecute(T data);
}
使用:
public class MyTask implements ITaskProcesser<RequestData, ResponseRet>{
.....
}
3、泛型方法:
泛型方法的基本介绍
/**
* 泛型方法的基本介绍
* @param tClass 传入的泛型实参
* @return T 返回值为T类型
* 说明:
* 1)public 与 返回值中间<T>非常重要,可以理解为声明此方法为泛型方法。
* 2)只有声明了<T>的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
* 3)<T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
* 4)与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。
*/
public <T> T genericMethod(Class<T> tClass)throws InstantiationException ,
IllegalAccessException{
T instance = tClass.newInstance();
return instance;
}
还可以
public static <T extends BaseEnum> T getEnumByCode(Class<T> targetType, Object code) {
}
使用
public class PendingTaskPool<T> {
public void show_1(T t){
System.out.println(t.toString());
}
//在泛型类中声明了一个泛型方法,使用泛型E,这种泛型E可以为任意类型。可以类型与T相同,也可以不同。
//由于泛型方法在声明的时候会声明泛型<E>,因此即使在泛型类中并未声明泛型,编译器也能够正确识别泛型方法中识别的泛型。
public <E> void show_3(E t){
System.out.println(t.toString());
}
//在泛型类中声明了一个泛型方法,使用泛型T,注意这个T是一种全新的类型,可以与泛型类中声明的T不是同一种类型。
public <T> void show_2(T t){
System.out.println(t.toString());
}
//这也不是一个泛型方法,这也是一个普通的方法,只不过使用了泛型通配符?
//同时这也印证了泛型通配符章节所描述的,?是一种类型实参,可以看做为Number等所有类的父类
public void registerTask(int taskLength, String taskName, ITaskProcesser<?, ?> task) {
//如果写成jobInfo.getTaskProcesser().taskExecute(data)
TaskResult<?> result = taskProcesser.taskExecute(data);
JobInfo<?> jobInfo = new JobInfo<>(taskLength, taskName, task);
jobInfoMap.put(jobInfo.getTaskName(), jobInfo);
}
}
注意:
当jobInfo 类型为
public class JobInfo<R> {
}
getTaskProcesser方法声明为:
public class JobInfo<R> {
private ITaskProcesser<?, ?> taskProcesser;
public ITaskProcesser<?, ?> getTaskProcesser() {
return taskProcesser;
}
}
taskExecute方法声明为:
public interface ITaskProcesser<R, T> {
public TaskResult<R> taskExecute(T data);
}
调用
jobInfo.getTaskProcesser().taskExecute(data)
报错:
The method taskExecute(capture#2-of ?) in the type ITaskProcesser<capture#1-of ?,capture#2-of ?> is not applicable for the arguments (T)
这是因为在调用jobInfo.getTaskProcesser()返回的是ITaskProcesser<?, ?>,与实际的ITaskProcesser<R, T>匹配不了,而?又避免不了不用,这个时候怎么办呢?改为如下:
ITaskProcesser taskProcesser = jobInfo.getTaskProcesser();
TaskResult<R> result = taskProcesser.taskExecute(data);
成功解决,很实用,经常会用到