服务器测评网
我们一直在努力

java泛型怎么使用

Java泛型是Java SE 5.0引入的重要特性,它允许在定义类、接口或方法时使用类型参数,从而在编译时提供类型检查,避免运行时的ClassCastException,同时提高代码的可重用性和可读性,泛型的核心思想是将“类型”作为参数进行传递,让代码能够适用于多种数据类型,同时保持类型安全。

java泛型怎么使用

泛型类的基本定义与使用

泛型类是在类名后面加上尖括号<>,其中包含一个或多个类型参数,定义一个泛型类Box,用于存储任意类型的对象:

class Box<T> {
    private T content; // T是类型参数,代表未知类型
    public void setContent(T content) {
        this.content = content;
    }
    public T getContent() {
        return content;
    }
}

使用时,需要在创建实例时指定具体的类型,称为“泛型实例化”,存储Integer类型的Box

Box<Integer> integerBox = new Box<>();
integerBox.setContent(123);
Integer value = integerBox.getContent(); // 无需强制类型转换

如果尝试传入不匹配的类型(如string),编译器会直接报错,避免了运行时类型转换的风险,泛型类可以有多个类型参数,例如class Pair<K, V>,分别表示键和值的类型。

泛型方法的灵活应用

除了泛型类,还可以定义泛型方法,泛型方法的类型参数位于返回类型之前,与类无关,可以在任何方法中使用,定义一个泛型方法用于交换数组中的两个元素:

public class ArrayUtils {
    public static <T> void swap(T[] array, int i, int j) {
        T temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}

调用时,编译器会根据传入的参数自动推断类型参数,也可以显式指定:

String[] names = {"Alice", "Bob"};
ArrayUtils.<String>swap(names, 0, 1); // 显式指定类型
// 或直接调用:ArrayUtils.swap(names, 0, 1); // 自动推断

泛型方法的优势在于,即使在不使用泛型的类中,也能实现针对多种类型的灵活操作。

java泛型怎么使用

泛型接口的实现

泛型接口的定义与泛型类类似,例如定义一个泛型接口Container,要求实现类提供存储和获取元素的方法:

interface Container<T> {
    void add(T item);
    T get();
}

实现类可以选择指定具体类型,例如StringContainer实现Container<String>

class StringContainer implements Container<String> {
    private String item;
    @Override
    public void add(String item) {
        this.item = item;
    }
    @Override
    public String get() {
        return item;
    }
}

也可以保留泛型类型,让实现类决定具体类型,例如GenericContainer<T>实现Container<T>,此时创建实例时需指定类型。

通配符的使用:灵活处理泛型类型

通配符()是泛型中的高级特性,用于表示未知类型,分为无界通配符、上限通配符和下限通配符,解决了泛型类型不可变的问题。

  • 无界通配符:表示任意类型,常用于处理未知类型的数据。printList方法可以打印任意类型的List

    public static void printList(List<?> list) {
        for (Object obj : list) {
            System.out.println(obj);
        }
    }
  • 上限通配符? extends T:表示类型参数是T或其子类,适用于读取操作(生产者模式)。List<? extends Number>可以存储IntegerDoubleNumber的子类,但无法向其中添加元素(因为不确定具体类型):

    java泛型怎么使用

    List<? extends Number> numberList = new ArrayList<Integer>();
    // numberList.add(10); // 编译错误,无法确定具体类型
    Number num = numberList.get(0); // 可以安全读取
  • 下限通配符? super T:表示类型参数是T或其父类,适用于写入操作(消费者模式)。List<? super Integer>可以存储IntegerNumberObject,可以安全添加Integer及其子类:

    List<? super Integer> superList = new ArrayList<Number>();
    superList.add(10); // 允许添加Integer
    Object obj = superList.get(0); // 读取时只能用Object类型

泛型的注意事项

使用泛型时需注意以下几点:

  1. 类型擦除:Java泛型在编译后会被擦除为原始类型(如T擦除为Object),因此运行时无法获取泛型类型信息,例如new T()是错误的,instanceof也不能用于泛型类型(如list instanceof List<String>会报错)。
  2. 基本数据类型不支持:泛型类型参数必须是引用类型(如Integer而非int),因为泛型 internally 使用Object存储数据。
  3. 静态上下文限制:静态变量或静态方法不能使用类的类型参数,因为静态成员属于类级别,而类型参数实例化时才确定。

通过合理使用泛型,可以编写出更安全、更灵活、可重用性更高的代码,无论是定义泛型类、方法,还是利用通配符处理复杂类型场景,泛型都能显著提升Java程序的质量和可维护性。

赞(0)
未经允许不得转载:好主机测评网 » java泛型怎么使用