探秘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的世界里游刃有余。