学习

https://www.bilibili.com/video/BV1YE411e75r?from=search&seid=14445431591523715474

概念

  1. JDK1.5 开始支持

  2. 作用:类型限定,例如 List 就限定了 List 元素为 String 类型

  3. 本质:

    1. 把对象/集合里面元素的类型推迟到创建的时候「定义时为泛型,使用时确定具体类型」
    2. 类型参数化
  4. 泛型格式

    <数据类型> 数据类型:只能是引用类型,不能为基本类型

  5. 使用格式

    数据类型<泛型的类型> 对象 = new 数据类型<泛型的类型>();

    // jdk 1.7 泛型推断,可简写如下:
    数据类型<泛型的类型> 对象 = new 数据类型();

    //泛型无效写法:

    数据类型 对象 = new 数据类型<泛型的类型>();

  6. 好处

  7. 可以限定类型,避免类型转换的错误

  8. 可以把运行时的异常提前到编译期

  9. 避免警告提示

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {

List<T> findAll();

List<T> findAll(Sort sort);

List<T> findAllById(Iterable<ID> ids);

<S extends T> List<S> saveAll(Iterable<S> entities);

void flush();

<S extends T> S saveAndFlush(S entity);

void deleteInBatch(Iterable<T> entities);

void deleteAllInBatch();

T getOne(ID id);

@Override
<S extends T> List<S> findAll(Example<S> example);

@Override
<S extends T> List<S> findAll(Example<S> example, Sort sort);
}

泛型类

Classname<T, E>

1
2
3
4
5
6
7
8
9
10
11
class Test<T, E> {
public void test(T t, E e) {
System.out.println(t);
System.out.println(e);
}
}

public static void main(String[] args) {
Test<String, Integer> test = new Test<>();
test.test("name", 12);
}

泛型接口

Interfacename<T, E>

1
2
3
4
5
6
7
8
9
10
11
interface Test<T, E> {
void test(T t, E e);
}

public static void main(String[] args) {
Test<String, Integer> test = (t, e) -> {
System.out.println(t);
System.out.println(e);
};
test.test("name", 12);
}

泛型方法

<T, E> returntype method(T t, E e)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static <T> IPage<T> getPageInfo(ApiResponse apiResponse, Class<T> clazz) {
List<T> listData = JSON.parseArray(JSON.toJSONString(apiResponse.getData()), clazz);
PageInfo page = apiResponse.getPage();
IPage<T> pageList = new Page<>();
pageList.setTotal(page.getTotal());
pageList.setCurrent(page.getPage());
pageList.setSize(page.getSize());
pageList.setRecords(listData);
return pageList;
}
// PageInfo.getPageInfo(apiResponse, VideoLiveAddress.class)

class Test {
public <T, E> void test(T t, E e) {
System.out.println(t);
System.out.println(e);
}
}
Test test = new Test();
test.test("name", 12);

有界范型

通配符

注意:泛型通配符不是用在定义对象上,用在方法形参上

有界通配符

  1. 无边界的通配符
  2. ? extends E 向下限定, E是上边界, ?是E及其子类
  3. ? super E 向上限定, E是下边界, ?是E及其父类

协变

  1. 数组可协变,多态
  2. 集合不可协变,应该使用泛型通配符