泛型方法
本课属于 Coddy Java 学习旅程的“面向对象编程”单元。第 55 课,共 87 课。
泛型类可以让整个类适用于不同类型,但有时你只需要一个方法是泛型的。泛型方法会声明自己的类型参数,不依赖类级别的泛型。
类型参数出现在方法签名中的返回类型之前:
public class Utility {
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.println(element);
}
}
}
String[] names = {"Alice", "Bob"};
Integer[] numbers = {1, 2, 3};
Utility.printArray(names); // 适用于 String[]
Utility.printArray(numbers); // 适用于 Integer[]注意,<T> 位于修饰符和返回类型之间。它将 T 声明为此方法的类型参数。编译器会根据你传入的参数推断出实际类型。
泛型方法也可以返回泛型类型:
public static <T> T getFirst(T[] array) {
if (array.length > 0) {
return array[0];
}
return null;
}
String first = getFirst(new String[]{"a", "b"}); // 返回 "a"需要时,你可以使用多个类型参数:
public static <K, V> void printPair(K key, V value) {
System.out.println(key + ": " + value);
}
printPair("Age", 25); // String 和 Integer
printPair(1, "First"); // Integer 和 String当你需要灵活、可复用的操作,但又不想创建泛型类时,泛型方法在工具类中尤其有用。
挑战
简单让我们构建一个实用工具包,展示泛型方法的灵活性。你将创建一个包含可重用方法的类,这些方法适用于任何类型,从而演示泛型方法可以独立于泛型类存在。
你将把代码分成两个文件:
ArrayUtils.java:创建一个包含数组操作泛型方法的工具类。你的类应包含三个静态泛型方法:getLast:一个泛型方法,接收一个类型为T的数组,并返回最后一个元素。如果数组为空,则返回null。swap:一个泛型方法,接收一个类型为T的数组和两个整数索引,然后交换这两个位置上的元素。此方法不返回任何内容。printWithLabel:一个包含两个类型参数K和V的泛型方法。它接收一个类型为K的标签和一个类型为V的值,然后按以下格式打印它们:[label]: [value]Main.java:使用你的泛型方法!你将收到 4 个输入:两个单词(字符串)和两个数字(整数)。首先,创建一个包含这两个单词的
String[]数组。使用getLast获取最后一个元素,并打印:Last word: [result]接下来,创建一个包含这两个数字的
Integer[]数组。调用swap交换索引 0 和 1 处的元素,然后打印:After swap: [first], [second]最后,通过调用两次
printWithLabel,演示这个带两个参数的泛型方法:- 第一次,以第一个单词作为标签,第一个数字作为值
- 第二次,以第一个数字作为标签,第二个单词作为值
你将按顺序收到 4 个输入:第一个单词、第二个单词、第一个数字、第二个数字。
注意,每个方法都会在返回类型之前用 <T> 或 <K, V> 声明自己的类型参数。编译器会根据你传入的参数推断实际类型:调用这些方法时,无需显式指定类型!
亲手试试
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取输入
String firstWord = scanner.nextLine();
String secondWord = scanner.nextLine();
int firstNumber = scanner.nextInt();
int secondNumber = scanner.nextInt();
// TODO: 创建一个包含两个单词的 String[] 数组
// TODO: 使用 ArrayUtils.getLast 获取最后一个元素
// 输出:"Last word: [result]"
// TODO: 创建一个包含两个数字的 Integer[] 数组
// TODO: 调用 ArrayUtils.swap,交换索引 0 和 1 处的元素
// 输出:"After swap: [first], [second]"
// TODO: 调用 ArrayUtils.printWithLabel,将 firstWord 作为标签,firstNumber 作为值
// TODO: 调用 ArrayUtils.printWithLabel,将 firstNumber 作为标签,secondWord 作为值
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Java 在线编译器