第2课_Java的泛型
热度🔥:50 免费课程
授课语音
Java 泛型
本课内容涵盖泛型的概念、定义泛型类、泛型接口、泛型方法、通配符、上下限、支持的类型、包装类和最佳实践等内容,附带详细的代码示例和中文注释,帮助您深入理解泛型的用法及应用场景
1. 认识泛型
介绍
泛型是一种参数化类型的机制,允许类、接口和方法在编写时不指定具体的数据类型,而在使用时通过传入实际类型进行实例化。泛型可以提高代码的复用性和安全性,并减少类型转换的错误。
作用
使用泛型的主要目的是提高类型安全性,避免在运行时因类型转换错误导致的 ClassCastException
。泛型的类型检查是在编译阶段进行的,可以有效避免代码在运行时出现类型不匹配的问题。
2. 自定义泛型类
介绍
Java 支持在定义类时使用泛型参数。定义泛型类时,通常使用 <T>
表示类型参数 T
,这个 T
可以在类中表示任意类型,实例化时再传入实际的类型。
代码示例
// 定义一个泛型类 Box,T 是类型参数
public class Box<T> {
private T item; // 泛型属性,类型为 T
// 构造方法
public Box(T item) {
this.item = item;
}
// 获取 item 值
public T getItem() {
return item;
}
// 设置 item 值
public void setItem(T item) {
this.item = item;
}
// 打印 item 信息
public void printInfo() {
System.out.println("Item: " + item);
}
}
// 测试自定义泛型类 Box 的使用
public class Main {
public static void main(String[] args) {
// 创建一个 Integer 类型的 Box
Box<Integer> integerBox = new Box<>(123);
integerBox.printInfo(); // 输出:Item: 123
// 创建一个 String 类型的 Box
Box<String> stringBox = new Box<>("Hello");
stringBox.printInfo(); // 输出:Item: Hello
}
}
3. 泛型接口
介绍
Java 支持接口使用泛型参数。通过定义泛型接口,可以让实现类根据需求指定类型,从而实现更加通用的接口设计。
代码示例
// 定义泛型接口 Container,类型参数为 T
public interface Container<T> {
void add(T item); // 添加元素
T get(int index); // 获取元素
}
// 实现泛型接口 Container,并指定类型参数为 String
public class StringContainer implements Container<String> {
private List<String> items = new ArrayList<>();
@Override
public void add(String item) {
items.add(item);
}
@Override
public String get(int index) {
return items.get(index);
}
}
// 测试泛型接口的实现
public class Main {
public static void main(String[] args) {
Container<String> stringContainer = new StringContainer();
stringContainer.add("Hello");
System.out.println(stringContainer.get(0)); // 输出:Hello
}
}
4. 泛型方法
介绍
Java 支持在类中定义泛型方法。泛型方法可以定义在普通类中,也可以定义在泛型类中。在方法定义中使用 <T>
表示这是一个泛型方法,可以接受任意类型的参数。
代码示例
public class GenericMethodExample {
// 定义一个泛型方法 printArray,类型参数为 T
public static <T> void printArray(T[] array) {
for (T item : array) {
System.out.println(item);
}
}
public static void main(String[] args) {
// 打印 Integer 数组
Integer[] intArray = {1, 2, 3, 4};
printArray(intArray);
// 打印 String 数组
String[] strArray = {"A", "B", "C"};
printArray(strArray);
}
}
5. 通配符
介绍
Java 泛型提供了通配符 ?
,用于表示未知类型。通配符主要用于泛型的读取操作,当我们不确定具体类型但只需要读取数据时可以使用通配符。
代码示例
public class WildcardExample {
// 使用通配符 ? 打印任意类型的 List
public static void printList(List<?> list) {
for (Object item : list) {
System.out.println(item);
}
}
public static void main(String[] args) {
List<Integer> intList = Arrays.asList(1, 2, 3);
List<String> strList = Arrays.asList("Hello", "World");
printList(intList); // 输出:1 2 3
printList(strList); // 输出:Hello World
}
}
6. 上下限
介绍
Java 泛型允许指定类型的上下限:
? extends T
:表示类型必须为T
或T
的子类,常用于读取操作。? super T
:表示类型必须为T
或T
的父类,常用于写入操作。
代码示例
public class BoundExample {
// 上限:只允许 T 或其子类的 List
public static void printNumbers(List<? extends Number> list) {
for (Number num : list) {
System.out.println(num);
}
}
// 下限:只允许 T 或其父类的 List
public static void addInteger(List<? super Integer> list) {
list.add(10);
list.add(20);
}
public static void main(String[] args) {
List<Integer> intList = new ArrayList<>(Arrays.asList(1, 2, 3));
printNumbers(intList); // 输出:1 2 3
List<Number> numList = new ArrayList<>();
addInteger(numList);
System.out.println(numList); // 输出:[10, 20]
}
}
7. 支持的类型与包装类
介绍
Java 泛型只支持引用类型,不支持基本类型(如 int
、char
等)。因此,使用泛型时需用包装类(如 Integer
、Double
等)来替代基本类型。
代码示例
public class WrapperExample {
public static void main(String[] args) {
// 使用包装类 Integer 替代基本类型 int
List<Integer> list = new ArrayList<>();
list.add(10); // 自动装箱
list.add(20);
System.out.println(list); // 输出:[10, 20]
}
}
8. 泛型的最佳实践
介绍
在实际开发中,合理使用泛型可以极大提升代码的复用性和类型安全性。以下是一些泛型的最佳实践:
- 在集合中使用泛型:使用集合时添加泛型声明,确保集合中存储的数据类型一致,减少类型转换错误。
- 避免混用原始类型:原始类型和泛型类型混用可能导致类型转换异常。
- 使用通配符:当不需要指定泛型类型时,可以使用通配符
?
以提高代码的灵活性。
代码示例
import java.util.ArrayList;
import java.util.List;
public class BestPracticeExample {
public static void main(String[] args) {
// 推荐:在集合中声明泛型类型
List<String> stringList = new ArrayList<>();
stringList.add("Hello");
// 使用通配符打印集合内容
printCollection(stringList);
}
// 使用通配符 ? 表示不限定类型,适用于各种类型的集合
public static void printCollection(List<?> list) {
for (Object item : list) {
System.out.println(item);
}
}
}
总结
Java 泛型是一种非常重要的工具,通过参数化类型使代码更具通用性和安全性。无论是泛型类、泛型接口还是泛型方法,合理使用泛型可以避免类型转换错误,提高代码的重用性和安全性。同时,上下限、通配符和包装类等特性使得泛型更加灵活,适用于各种复杂的应用场景。