Java泛型

sdjasj

泛型

  • 如果Foo是 Bar的一个子类型(子类或者子接口),而 G是具有泛型声明的类或接口,G<Foo>并不是G<Bar>的子类型
  • 数组和泛型有所不同,假设Foo是Bar 的一个子类型(子类或者子接口),那么Foo[]依然是 Bar[]的子类型;但 G<Foo>不是 G<Bar>的子类型。

深入泛型

创建泛型

1
2
3
4
5
6
7
8
//定义类时定义了一个形参T
public class A<T> {
//在类里T可以作为参数类型使用
T a;
public T add(T a, T b) {

}
}
  • 包含泛型声明的类型可以在定义变量、创建对象时传入一个类型实参,从而可以动态地生成无数多个逻辑上的子类,但这种子类在物理上并不存在。

泛型类派生子类

当创建了带泛型声明的接口、父类之后,可以为该接口创建实现类,或从该父类派生子类,需要指出的是,当使用这些接口、父类时不能再包含类型形参

1
2
3
class A extends B<T> //错误
class A extends B<String> //正确
class A extends B //警告,会把T默认当初Object

类型通配符

简介

类型通配符一般是使用 ? 代替具体的类型参数。例如 List<?> 在逻辑上是List<String>、List<Integer>

等所有 List<具体类型实参> 的父类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.*;

public class GenericTest {

public static void main(String[] args) {
List<String> name = new ArrayList<String>();
List<Integer> age = new ArrayList<Integer>();
List<Number> number = new ArrayList<Number>();

name.add("icon");
age.add(18);
number.add(314);

getData(name);
getData(age);
getData(number);

}

public static void getData(List<?> data) {
System.out.println("data :" + data.get(0));
}
}

类型通配符上限

List<? extends A>表示只能传入A及A的子类,同时,因为无法确定List中的类型是什么,所以List<?>无法添加任何元素(除了null)

类型通配符下限

下限:<? super T> ?是T和T的父类

  • Treeset构造器有形参Treeset(Comparator<? super E>),表示可以按照Treeset类型参数及其父类来进行排序

  • 可以添加T或者T的子类,但取出的一定是object类

设定类型形参上限

1
2
3
4
5
6
7
8
9
//定义类时定义了一个形参T
//使用A类时为T形参传入的实际参数只能是Number或Number的子类
public class A<T extends Number> {
//在类里T可以作为参数类型使用
T a;
public T add(T a, T b) {

}
}

泛型方法

09221852-b0d764f4340946baa1a063da5a0d993e

泛型方法也可以设定上限

image-20220226202701317

  • 標題: Java泛型
  • 作者: sdjasj
  • 撰寫于: 2022-02-26 20:46:27
  • 更新于: 2022-07-18 09:30:05
  • 連結: https://redefine.ohevan.com/2022/02/26/Java泛型/
  • 版權宣告: 本作品采用 CC BY-NC-SA 4.0 进行许可。
 留言