Java 基础 - 泛型
# 为什么使用泛型
泛型其实就是将类型参数化,从而提高参数类型的表达能力。泛型可以使用在类、接口和方法上,分别被称为泛型类、泛型接口和泛型方法,使用泛型的优势有:
- 泛型可以使得程序在编译期间就发现类型匹配问题,而不是在运行期间发现问题。
- 泛型可以明确特定对象实例化时的类型信息,避免不必要的类型转换。
- 泛型可以提高代码重用性。
# 语法
泛型的标识是在一对尖括号“<>”中包含类型参数,其中的类型参数可以有一个或多个,如:<T>
、<T, U>
、<K, V>
。从语法上来说,类型参数可以是任意字符。但是从开发规范的角度来讲,一般都是采用简短的大写字母来表示:
- 用
E
表示集合元素; K
和V
分别表示键和值;T
可以表示任意类型,如果有多个任意类型时,可以使用和T
相邻的字母,如:U
、S
。
# 泛型类
class Result<T> {
private T data;
public Result() {
}
public Result(T data) {
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 泛型接口
interface Result<T> {
public void test1(T data);
public T test2();
}
1
2
3
4
5
6
2
3
4
5
6
# 泛型方法
class Result {
public <K, V> V getObject(K key, V value) {
// pass
return value;
}
}
1
2
3
4
5
6
2
3
4
5
6
在getObject
方法签名中从左往右依次解释:
- 先出现的
<K, V>
表示该方法中允许使用两个类型参数,分别是K
和V
。 - 接下来出现的
V
表示该方法的返回类型为V
。 (K key, V value)
表示该方法有两个参数key
和value
,参数类型分别是K
和V
。
# 泛型通配符
泛型的表达能力是非常强的,在某些场景下,如果需要限定一个类型范围,而不是某个具体类型的时候,就需要使用类型限定符或类型通配符。类型限定符可以归结为下面几种类型:
<?>
,表示无限制通配符。<T extends BoundingType>
,表示 T 只能是BoundingType
本身或它的子类。<? extends BoundingType>
,表示限定的类型只能是BoundingType
本身或它的子类。<T extends BoundingTypeA & BoundingTypeB & BoundingTypeC>
,一个类型变量有多个限定,但是由于 Java 单继承的特点,所以只能有一个限定符是类,二其它限定符必须是接口,且如果有类出现的话,类必须是出现在第一个位置的。在表达式<T extends BoundingTypeA & BoundingTypeB & BoundingTypeC>
中,BoundingTypeA
必须是类或接口,BoundingTypeB
和BoundingTypeC
只能是接口。<? super BoundingType>
表示限定的类型只能是BoundingType
本身或它的父类。
提示
<T extends BoundingType>
和 <? extends BoundingType>
有什么区别?
<T extends BoundingType>
用于定义类型参数,它声明了一个类型参数 T,可以放在泛型类的类名后面或泛型方法的返回值前面。<? extends BoundingType>
用于实例化泛型变量中的类型参数,只是具体类型是未知的,放在方法的泛型参数中。
public class Test<T extends Number> {
public static void main(String[] args) throws Exception {
test(new Test<A>());
}
public static <T extends Number> void test(Test<? extends Number> a) {
}
}
class A extends Number {
@Override
public int intValue() {
return 0;
}
@Override
public long longValue() {
return 0;
}
@Override
public float floatValue() {
return 0;
}
@Override
public double doubleValue() {
return 0;
}
}
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
27
28
29
30
31
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
27
28
29
30
31
# 使用原则
通配符的规则整体上可以分为 extends 和 super 两类,具体的使用原则是:
- 如果参数化的类型是生产者,则使用
<T extends BoundingType>
。 - 如果参数化的类型是消费者,则使用
<T super BoundingType>
。
上次更新: 2023/11/01, 03:11:44