教程中心 / Java教程 / 泛型类

泛型类

12分钟 泛型

什么是泛型类?

泛型类是带有类型参数的类。简单来说,就是把泛型参数作为类的一部分来定义。泛型类最常见的用途是创建可重用的容器类

生活比喻

泛型类就像一个万能收纳盒。你可以把它当成"文件盒"、"药盒"、"工具盒"...每个盒子的结构一样,但里面装的东西不同。泛型类就是这样的模具,给你什么类型参数,它就变成什么类型的容器。

泛型类的定义和使用

基础泛型类

// 定义泛型类 - 类名后面跟
class Box {
    private T content;

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

    public T get() {
        return content;
    }
}

// 使用时指定具体类型
Box stringBox = new Box<>();
stringBox.put("Hello World");
String message = stringBox.get();  // 自动是String类型

Box intBox = new Box<>();
intBox.put(123);
Integer number = intBox.get();  // 自动是Integer类型

多类型参数的泛型类

泛型类可以有多个类型参数,这在Map等场景中很常用:

// 两个类型参数的泛型类
class Pair {
    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; }

    // 交换功能
    public Pair swap() {
        return new Pair<>(value, key);
    }
}

// 使用
Pair score = new Pair<>("数学", 95);
System.out.println(score.getKey() + ": " + score.getValue());

Pair swapped = score.swap();
System.out.println(swapped.getKey() + ": " + swapped.getValue());

泛型接口

接口同样可以是泛型的,让实现类提供具体类型:

// 定义泛型接口
interface Container {
    void add(E element);
    E get(int index);
    int size();
    boolean isEmpty();
}

// 实现泛型接口 - 指定具体类型
class StringContainer implements Container {
    private String[] elements;
    private int size = 0;

    public StringContainer(int capacity) {
        elements = new String[capacity];
    }

    @Override
    public void add(String element) {
        if (size < elements.length) {
            elements[size++] = element;
        }
    }

    @Override
    public String get(int index) {
        if (index >= 0 && index < size) {
            return elements[index];
        }
        return null;
    }

    @Override
    public int size() { return size; }

    @Override
    public boolean isEmpty() { return size == 0; }
}

// 实现泛型接口 - 保留泛型
class GenericContainer implements Container {
    private Object[] elements;
    private int size = 0;

    public GenericContainer(int capacity) {
        elements = new Object[capacity];
    }

    @Override
    public void add(E element) {
        if (size < elements.length) {
            elements[size++] = element;
        }
    }

    @Override
    public E get(int index) {
        if (index >= 0 && index < size) {
            return (E) elements[index];
        }
        return null;
    }

    @Override
    public int size() { return size; }

    @Override
    public boolean isEmpty() { return size == 0; }
}

泛型类的类型限制

有时候你需要限制泛型类型参数的范围,这时可以使用泛型限定

上界限定(extends)

// 限制T必须是Number或其子类
class NumberBox {
    private T value;

    public void set(T value) {
        this.value = value;
    }

    public T get() {
        return value;
    }

    // 现在可以安全调用Number的方法
    public double toDouble() {
        return value.doubleValue();
    }
}

// 合法
NumberBox intBox = new NumberBox<>();
NumberBox doubleBox = new NumberBox<>();

// 非法 - String不是Number的子类
// NumberBox stringBox = new NumberBox<>();  // 编译错误!

多个上界

// T必须同时实现Comparable和Serializable
class ComparableBox & Serializable> {
    private T item;

    public void sortIfPossible(T other) {
        if (item.compareTo(other) > 0) {
            System.out.println("item > other");
        }
    }
}

泛型类的继承

泛型类可以继承泛型或非泛型类,也可以被泛型或非泛型类继承:

// 父类
class Animal { }

// 子类保留父类的泛型
class Dog extends Animal { }

// 子类具体化泛型
class StringDog extends Animal { }

// 子类添加新的泛型参数
class SpecialDog extends Dog {
    private R attribute;
}

泛型类的构造函数

泛型类的构造函数不需要重复声明泛型参数:

class Stack {
    private T[] array;
    private int top;

    // 构造函数不需要,因为T已经在类声明中声明
    public Stack(int capacity) {
        this.array = (T[]) new Object[capacity];
        this.top = 0;
    }

    public void push(T item) {
        if (top < array.length) {
            array[top++] = item;
        }
    }

    public T pop() {
        if (top > 0) {
            return array[--top];
        }
        return null;
    }
}

// 使用
Stack intStack = new Stack<>(10);
intStack.push(1);
intStack.push(2);
System.out.println(intStack.pop());  // 2

静态变量和泛型

重要:静态成员不能使用类的泛型类型参数

class WrongExample {
    private T instance;           // OK - 实例变量可以用T
    // private static T staticVar;  // 错误! 静态变量不能用T

    // 静态方法可以自己定义泛型参数
    public static  void print(E item) {
        System.out.println(item);
    }

    // 静态方法也可以使用类的泛型(但不推荐)
    public static  S getDefault(Supplier supplier) {
        return supplier.get();
    }
}

小结

  • 泛型类在类名后使用<T>声明类型参数
  • 可以使用多个类型参数如<K, V>
  • 泛型接口与泛型类的用法相同
  • 使用extends限定限制类型参数的范围
  • 静态成员不能使用类的泛型类型参数
  • 构造函数不需要重复声明泛型参数
☕ Java 在线代码编辑器
📝 运行结果

© 2026 码趣阁 - 让工作更高效