【java 泛型,看这一篇就够了】

54 阅读3分钟

Java 泛型概念解析与实践

引言

Java泛型是Java 5引入的一项强大特性,它允许在编译时提供类型安全,同时保持代码的灵活性。泛型的本质是参数化类型,即允许在定义类、接口和方法时使用一个或多个类型参数。这使得代码更加通用,可以操作多种数据类型,同时避免了类型转换和类转换异常。

泛型的基本使用

定义泛型类

泛型类可以通过在类名后添加类型参数来定义。类型参数通常用单个大写字母表示,如TEKV等。

public class Box<T> {
    private T t;

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

    public T get() {
        return t;
    }
}

使用泛型类

在使用泛型类时,可以指定具体的类型参数,或者让编译器推断类型参数。

Box<Integer> integerBox = new Box<>();
integerBox.set(10);
System.out.println(integerBox.get());

Box<String> stringBox = new Box<>();
stringBox.set("Hello, World!");
System.out.println(stringBox.get());

泛型的高级特性

泛型方法

泛型方法是指具有自己的类型参数的方法。这使得方法可以在不同的数据类型上复用。

public <T> void printArray(T[] inputArray) {
    for (T item : inputArray) {
        System.out.print(item + " ");
    }
    System.out.println();
}

泛型接口

泛型接口允许定义操作一组对象的方法,而不需要指定具体的类型。

public interface Generator<T> {
    T next();
}

通配符

通配符?用于表示未知的类型。它可以用来定义可以操作任何类型的泛型类或方法。

public static <T> void printArrayElements(List<?> list) {
    for (Object element : list) {
        System.out.print(element + " ");
    }
    System.out.println();
}

泛型的类型限制

无界通配符

无界通配符<?>表示可以是任何类型的对象。

List<?> list = new ArrayList<>();
list.add("String");
list.add(1);

有界通配符

有界通配符允许指定类型参数的上界或下界。

List<? extends Number> numberList = new ArrayList<>();
numberList.add(1);
numberList.add(2.0);

List<? super String> stringList = new ArrayList<>();
stringList.add("String");
stringList.add(new Object());

泛型与继承

协变与逆变

泛型在继承关系中表现出协变和逆变的特性。

List<Dog> dogs = new ArrayList<>();
List<Animal> animals = dogs; // 错误:逆变
List<Animal> animals = new ArrayList<Dog>(); // 正确:协变

泛型的实际应用

集合框架

Java集合框架广泛使用了泛型,以确保类型安全。

List<String> stringList = new ArrayList<>();
stringList.add("Hello");
String str = stringList.get(0);

排序算法

泛型使得排序算法可以对任何类型的数据进行排序。

public <T extends Comparable<T>> void sort(T[] array) {
    for (int i = 0; i < array.length - 1; i++) {
        for (int j = 0; j < array.length - i - 1; j++) {
            if (array[j].compareTo(array[j + 1]) > 0) {
                T temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
            }
        }
    }
}

泛型的局限性

类型擦除

Java泛型在运行时会进行类型擦除,这意味着泛型信息不会保留在字节码中。

泛型与反射

泛型与反射一起使用时可能会遇到问题,因为反射操作的是类型擦除后的类。

结论

Java泛型提供了一种在编译时检查类型安全的方法,同时保持了代码的灵活性和重用性。通过合理使用泛型,可以编写出更加健壮和易于维护的代码。然而,泛型也有其局限性,如类型擦除和与反射的兼容性问题,开发者在使用时应充分理解这些特性和限制。