java泛型的全面使用

概念

泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?

顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),

然后在使用/调用时传入具体的类型(类型实参)。

使用

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 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);

成功解决,很实用,经常会用到

猜你喜欢

转载自blog.csdn.net/huangyung/article/details/106310638