Menu
CoddyTech

泛型方法

本课属于 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

当你需要灵活、可复用的操作,但又不想创建泛型类时,泛型方法在工具类中尤其有用。

challenge icon

挑战

简单

让我们构建一个实用工具包,展示泛型方法的灵活性。你将创建一个包含可重用方法的类,这些方法适用于任何类型,从而演示泛型方法可以独立于泛型类存在。

你将把代码分成两个文件:

  • 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 作为值
    }
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Java 在线编译器