Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 第四章:集合框架

第四章:集合框架

4.4 泛型

1. 泛型概述

泛型(Generics)是Java SE 5.0引入的一项重要特性,它允许在定义类、接口或方法时使用类型参数(Type Parameters)。泛型的主要目的是提供编译时的类型安全检查,并消除强制类型转换的需要。

泛型的主要优点:

  • 类型安全:编译时检查类型,避免运行时类型转换错误。
  • 代码复用:可以编写更通用的代码,减少重复。
  • 消除强制类型转换:使代码更简洁、可读性更高。

2. 泛型的基本语法

泛型通过尖括号<>定义类型参数,可以用于类、接口和方法。

2.1 泛型类

public class Box<T> {
    private T content;

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

    public T getContent() {
        return content;
    }
}
  • T是类型参数,可以是任何非基本数据类型(如String、Integer等)。
  • 使用时指定具体类型:
    Box<String> stringBox = new Box<>();
    stringBox.setContent("Hello, Generics!");
    

2.2 泛型接口

public interface List<T> {
    void add(T element);
    T get(int index);
}
  • 实现泛型接口时需指定具体类型:
    public class StringList implements List<String> {
        // 实现方法
    }
    

2.3 泛型方法

public <T> void printArray(T[] array) {
    for (T element : array) {
        System.out.println(element);
    }
}
  • 调用时无需显式指定类型(编译器自动推断):
    Integer[] intArray = {1, 2, 3};
    printArray(intArray);
    

3. 泛型通配符

泛型通配符?用于表示未知类型,通常用于方法参数或变量声明。

3.1 无界通配符

public void printList(List<?> list) {
    for (Object elem : list) {
        System.out.println(elem);
    }
}
  • 可以接受任何类型的List,但只能读取(不能写入)。

3.2 上界通配符(? extends T)

public double sumOfList(List<? extends Number> list) {
    double sum = 0.0;
    for (Number num : list) {
        sum += num.doubleValue();
    }
    return sum;
}
  • 表示类型是Number或其子类(如Integer、Double)。

3.3 下界通配符(? super T)

public void addNumbers(List<? super Integer> list) {
    list.add(1);
    list.add(2);
}
  • 表示类型是Integer或其父类(如Number、Object)。

4. 泛型擦除

Java的泛型是通过类型擦除(Type Erasure)实现的,即在编译时擦除类型信息,运行时只保留原始类型(Raw Type)。

4.1 擦除规则

  • 泛型类或方法中的类型参数会被替换为Object(无界类型)或上界类型。
  • 例如:
    List<String> list = new ArrayList<>();
    
    编译后等同于:
    List list = new ArrayList(); // 原始类型
    

4.2 泛型与数组的限制

  • 不能创建泛型数组:
    // 编译错误!
    List<String>[] array = new List<String>[10];
    
  • 但可以通过通配符实现:
    List<?>[] array = new List<?>[10];
    

5. 泛型的实际应用

5.1 集合框架中的泛型

List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
// names.add(123); // 编译错误!

5.2 自定义泛型工具类

public class Pair<K, V> {
    private K key;
    private V value;

    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public K getKey() { return key; }
    public V getValue() { return value; }
}

6. 常见问题与注意事项

  1. 基本类型不能作为泛型参数:需使用包装类(如Integer代替int)。
  2. 泛型不能用于静态上下文的类型参数:
    public class Box<T> {
        // 错误!静态方法不能使用类的类型参数
        public static T staticMethod() { ... }
    }
    
  3. 避免过度使用通配符:可能降低代码可读性。

7. 总结

泛型是Java集合框架的核心特性之一,它通过类型参数化提高了代码的安全性和复用性。掌握泛型的使用和通配符规则,能够更高效地编写健壮的Java程序。


练习:

  1. 定义一个泛型方法,用于交换数组中两个元素的位置。
  2. 创建一个泛型类Cache,支持存储任意类型的值,并提供获取和设置方法。
Last Updated:: 3/27/25, 12:48 PM