泛型(Generics)是一种参数化类型的概念
它使得我们可以编写能够适用于多种类型的代码,而不是为每种类型都写一份代码。泛型提供了编译时的类型检查,使得代码更加安全,并且减少了在运行时进行频繁的类型转换
例如:
我们之前有为很多箱子都贴上了固定的标签!
装 苹果,老鼠,小狗,因为不能放一起呀!虽然,狗现在已经不多管闲事去拿耗子啦_
有多少种类就需要多少箱子,新增加一个就需要再增加,就很麻烦
之前的 苹果,老鼠,小狗等等箱子,就是具体的类型。而后来的 东西,就是一个泛型。
在 Java 中,泛型主要通过在类
、接口
、方法
中使用泛型类型参数来实现。
下面就使用泛型去定义一个箱子
// 定义一个泛型类(比如这就是一个装东西的箱子)
class Box<T> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
上述代码中,Box
类使用了泛型类型参数 T
,使得这个类可以存储和返回任意类型的数据。
使用上面已经定义好的箱子去装各种各样的东西
先往里装一种类型的东西,如老鼠
public static void main(String[] args) {
// 可以往箱子里装 int 型数字(比如这就是老鼠)
Box<Integer> integerBox = new Box<>();
integerBox.setValue(42);
int intValue = integerBox.getValue();
System.out.println(intValue);
}
输出结果:42
再往里装另一种类型的东西,如小狗
public static void main(String[] args) {
// 还可以往箱子里装 String 型的字符(比如这就是小狗)
Box<String> stringBox = new Box<>();
stringBox.setValue("哈士奇");
String stringValue = stringBox.getValue();
System.out.println(stringValue);
}
输出结果:哈士奇
除了泛型类,Java 还支持泛型方法。泛型方法可以在普通类中定义,也可以在泛型类中定义。
以下是一个简单的泛型方法的例子:
// 定义一个泛型方法
public static <E> void printBoxSaveWhat(E e) {
System.out.println("箱子里装的是: " + e);
}
// 使用泛型方法
public static void main(String[] args) {
// 打印第一种类型
printBoxSaveWhat(42);
// 打印外一种类型
printBoxSaveWhat("哈士奇");
}
输出结果:
箱子里装的是: 42
箱子里装的是: 哈士奇
上述代码中,printBoxSaveWhat
方法是一个泛型方法,可以接受任意类型的参数。在使用时,编译器会根据传入的实际参数类型进行类型推断。
Java 泛型还引入了通配符和泛型上下界的特性。
用于表示未知类型
示例代码:
// 使用通配符
public static void printValues(List<?> values) {
for (Object value : values) {
System.out.println(value);
}
}
public static void main(String[] args) {
System.out.println("开始打印 整数");
List<Integer> integers = Arrays.asList(1, 2, 3);
printValues(integers);
System.out.println("开始打印 小数");
List<Double> doubles = Arrays.asList(1.1, 2.2);
printValues(doubles);
}
输出结果:
开始打印 整数
1
2
3
开始打印 小数
1.1
2.2
在上述代码中,printValues
方法使用了通配符 ?
,允许接受任意类型的 List。
用于限定泛型类型的范围
示例代码:
// 使用泛型上下界
public static <T extends Number> double sum(List<T> numbers) {
double total = 0;
for (T number : numbers) {
total += number.doubleValue();
}
return total;
}
public static void main(String[] args) {
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
System.out.println("整数的加和结果是: " + sum(integers));
List<Double> doubles = Arrays.asList(1.1, 2.2, 3.3, 4.4);
System.out.println("小数的加和结果是: " + sum(doubles));
}
输出结果:
整数的加和结果是: 15.0
小数的加和结果是: 11.0
在上述代码中, sum
方法使用了泛型上下界 T extends Number
,表示只能接受 Number 类型或其子类型
>
时,只能读取,无法修改泛型集合中的元素。如果需要修改,可以使用 extends T>
或 super T>
。List
不是 List
的子类型。用通配符 >
时,只能读取,无法修改泛型集合中的元素。如果需要修改,可以使用 extends T>
或 super T>
。
List
不是 List
的子类型。在实际编程中,合理利用泛型可以使代码更加健壮、灵活,但也需要注意一些泛型的特性和限制。通过了解和熟练使用泛型,可以写出更加清晰、安全和可维护的 Java 代码。