探秘Java泛型通配符与类型投影

在Java编程的世界里,泛型无疑是一把利器,它让我们的代码更加灵活和健壮。而泛型中的通配符和类型投影更是高级应用中的璀璨明珠。今天,我们就来深入探讨一下Java泛型通配符与类型投影的奥秘。

探秘Java泛型通配符与类型投影

泛型通配符:灵活的代名词

泛型通配符主要有三种形式:?、? extends T 和 ? super T。它们的出现,极大地提升了泛型的灵活性。

无界通配符 ?

无界通配符 ? 表示任意类型。比如,List<?> 可以表示任何类型的List。这种通配符在不知道具体类型的情况下非常有用。

List<?> list = new ArrayList<String>();
list = new ArrayList<Integer>();

上界通配符 ? extends T

上界通配符 ? extends T 表示某个类T或其子类的类型。这种通配符常用于读取操作,因为你可以确信获取到的元素至少是T类型的。

List<? extends Number> list = new ArrayList<Integer>();
Number number = list.get(0);

下界通配符 ? super T

下界通配符 ? super T 表示某个类T或其父类的类型。这种通配符常用于写入操作,因为你可以向其中添加T类型的元素。

List<? super Integer> list = new ArrayList<Number>();
list.add(1);

类型投影:精确的控制

类型投影是泛型中另一个高级概念,它允许我们在泛型类型中指定具体的类型参数。类型投影分为两种:协变投影和逆变投影。

协变投影

协变投影使用 ? extends T,它允许我们读取但不能写入。这是因为协变投影保证了读取出来的元素至少是T类型的,但无法保证写入的元素是安全的。

class Box<T> {
    private T content;

    public T getContent() {
        return content;
    }

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

Box<? extends Number> box = new Box<Integer>();
Number number = box.getContent();
// box.setContent(1); // 编译错误

逆变投影

逆变投影使用 ? super T,它允许我们写入但不能安全地读取。这是因为逆变投影保证了可以写入T类型的元素,但无法保证读取出来的元素是具体的T类型。

Box<? super Integer> box = new Box<Number>();
box.setContent(1);
// Integer integer = box.getContent(); // 编译错误

实战应用:灵活与安全的平衡

在实际开发中,泛型通配符和类型投影的应用非常广泛。比如,在集合操作中,我们可以利用通配符来编写更通用的方法。

public void printList(List<?> list) {
    for (Object elem : list) {
        System.out.println(elem);
    }
}

在这个例子中,printList 方法可以接受任何类型的List,极大地提升了代码的复用性。

再比如,在泛型类的设计中,我们可以利用类型投影来精确控制方法的读写权限。

class ReadOnlyBox<T> {
    private T content;

    public ReadOnlyBox(T content) {
        this.content = content;
    }

    public T getContent() {
        return content;
    }
}

class WriteOnlyBox<T> {
    private T content;

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

public void processBoxes(List<? extends ReadOnlyBox<?>> readOnlyBoxes, List<? super WriteOnlyBox<?>> writeOnlyBoxes) {
    for (ReadOnlyBox<?> box : readOnlyBoxes) {
        System.out.println(box.getContent());
    }
    writeOnlyBoxes.add(new WriteOnlyBox<>());
}

在这个例子中,processBoxes 方法利用了协变和逆变投影,精确地控制了读写权限,保证了代码的安全性和灵活性。

Java泛型通配符和类型投影是高级编程中不可或缺的工具,它们不仅提升了代码的灵活性和复用性,还通过精确的类型控制,保证了代码的安全性。掌握这些高级特性,无疑会让我们的Java编程水平更上一层楼。希望本文能为你揭开泛型通配符和类型投影的神秘面纱,让你在Java的世界里游刃有余。

你可能想看:
« 上一篇
下一篇 »

相关推荐

java中什么是冒泡,冒泡算法

2026年09月06日

27阅读

java中冒号,java双冒号

2026年09月06日

26阅读

java中的->,java中的是什么意思

2026年09月06日

24阅读

java中的super用法,Java中super的说明

2026年09月06日

28阅读

java中反射的应用,java中反射的应用场景

2026年09月06日

25阅读

java中开关的定义,Java关键字有哪些

2026年09月06日

25阅读