Java中的泛型:为何需要及如何使用

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Java 中的泛型:为何需要以及如何使用



泛型是 Java 语言的关键特性之一,自 J2SE 5.0 版本引入。它允许你创建适用于不同数据类型的类、接口和方法,同时在编译时保持强类型检查。在本文中,我们将探讨为何需要泛型、如何正确使用它们,以及它们能帮助避免哪些错误。



为何 Java 中需要泛型?



在泛型出现之前,程序员需要使用类型转换和操作 Object 类型。这导致了两个主要问题:



  • 缺乏类型安全性 — 任何类型的对象都可以被添加到集合中,错误只会在运行时出现。
  • 需要显式类型转换 — 从集合中获取元素时需要进行强制类型转换,使代码变得臃肿。


// 没有泛型(Java 5 之前)List list = new ArrayList();list.add("string");list.add(123); // 编译时没有错误String s = (String) list.get(0); // 必须显式转换


// 使用泛型List<String> list = new ArrayList<>();list.add("string");// list.add(123); // 编译错误!String s = list.get(0); // 不需要类型转换


泛型的主要优势:

  • 类型安全性 — 类型错误在编译时就被检测出来。
  • 消除显式类型转换 — 代码更简洁、更易读。
  • 代码可复用性 — 同一实现可适用于不同类型。


创建泛型类和方法



泛型类



要创建适用于任意类型的类,只需在类名后的尖括号中指定类型参数:



public class Box<T> {    private T content;

public void setContent(T content) { this.content = content; }

public T getContent() { return content; }

public static void main(String[] args) { Box<String> stringBox = new Box<>(); stringBox.setContent("Hello, Java!"); System.out.println(stringBox.getContent());

Box<Integer> intBox = new Box<>(); intBox.setContent(42); System.out.println(intBox.getContent()); }}


在这个例子中,T 是类型参数。当创建 Box<String> 对象时,所有出现 T 的地方都会被替换为 String。



泛型方法



方法也可以被参数化。类型参数在返回类型之前指定:



public class Util {    public static <T> void printArray(T[] array) {        for (T element : array) {            System.out.print(element + " ");        }        System.out.println();    }

public static void main(String[] args) { Integer[] intArray = {1, 2, 3, 4, 5}; String[] strArray = {"A", "B", "C"};

printArray(intArray); // 1 2 3 4 5 printArray(strArray); // A B C }}


注意:类型参数 <T> 位于 void 之前。这是泛型方法的强制要求。



有界类型参数



有时需要限制哪些类型可以用作参数。关键词 extends 和 super 用于此目的。



上界(extends)



从上方限制类型——只能使用指定的类本身或其子类:



public class Calculator<T extends Number> {    private T value;

public Calculator(T value) { this.value = value; }

public double square() { return va

博客

书籍推荐