一、什么是泛型?
在Java中,泛型是指在定义类和接口时允许使用类型参数,声明的类型参数在使用时才用具体的类型来替换。
为什么要使用泛型?:
- 代码复用:比如我们常用的
List
,我们平时要将String
、Integer
等类型放入List
中。如果没有泛型,那么我们需要针对每一个使用的类型都定义一个容器,如IntegerList、StringList,就会很麻烦 - 代码安全:对于某些场景只能传入某种类型的参数,如果传入了其他类型的参数就会有问题。比如有一个年龄列表
ArrayList<Integer>()
,如果没有泛型,传入了一个String
类型的话,那么是不符合场景逻辑的,更严重还会在某块代码逻辑报错
二、泛型有哪几种?
泛型一般分为三种,分别为:
- 泛型类
- 泛型接口
- 泛型方法
1、泛型类
public class Info<T> {
private T member;
// ...
}
如何实例化泛型类:
Info<User> userInfo = new Info<User>();
2、泛型接口
public interface Task<T> {
public T execute();
}
如何实现泛型接口:
// 不指定类型
class TaskImpl<T> implements Task<T> {
@Override
public T execute() {
// ...
}
}
// 指定类型
class TaskImpl<T> implements Task<String> {
@Override
public String execute() {
// ...
}
}
3、泛型方法
public static <E> void printArray(E[] array) {
for(E e : array) {
System.out.println(e);
}
}
使用方法如下:
Integer[] intArray = {1,2,3};
String[] strArray = {"a","b","c"};
printArray(intArray);
printArray(<)strArray);
三、泛型的使用场景
泛型的使用场景一般有:
- 通用结果返回:比如Http接口我们想封装一层Http结构体,但是数据源是不确定的,所以可以定义成
CommonResult<T>
- 集合类:如
List
、Set
等集合都用到了泛型
简单总结来说就是有相同特征的场景,但是传参根据实际场景确定
四、Q&A
1、如何在ArrayList()中添加一个String类型的对象?
正常的add()
是没办法实现的,因为非Integer
添加时编译器会报错。
所以我们可以借助反射机制来实现:
List<Integer> list = new ArrayList<Integer>();
Method method = list.getClass().getMethod("add", Object.class);
method.invoke(list, "test"); // ["test"]