泛型的上界通配符和下界通配符
背景和价值
上界通配符(? extends T)
在泛型中,? extends T 表示通配符的上界,即这个泛型类型必须是 T 类或者 T 的子类。使用上界通配符可以实现更灵活的泛型方法和泛型类的使用。
在集合里使用上界通配符是很常见的,它能让方法处理包含特定类型及其子类对象的集合,增强代码的灵活性和复用性。
import java.util.ArrayList;
import java.util.List;
// 定义一个父类
class Fruit {
public void eat() {
System.out.println("Eating a fruit.");
}
}
// 定义一个子类
class Apple extends Fruit {
@Override
public void eat() {
System.out.println("Eating an apple.");
}
}
// 定义一个方法,接受一个水果列表
public class Main {
public static void printFruits(List<? extends Fruit> fruits) {
for (Fruit fruit : fruits) {
fruit.eat();
}
}
public static void main(String[] args) {
List<Apple> apples = new ArrayList<>();
apples.add(new Apple());
printFruits(apples); // 可以传入 Apple 列表
}
}
上界通配符可以用在泛型方法的参数中,让方法能处理不同类型但具有继承关系的对象。
class Shape {
public double area() {
return 0;
}
}
class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius;
}
}
public class GenericMethodExample {
public static <T extends Shape> double totalArea(T shape1, T shape2) {
return shape1.area() + shape2.area();
}
public static void main(String[] args) {
Circle circle1 = new Circle(5);
Circle circle2 = new Circle(3);
double total = totalArea(circle1, circle2);
System.out.println("Total area: " + total);
}
}
下界通配符使用 ? super T 来定义,其中 T 是一个具体的类型。它表示泛型类型可以是 T 本身,或者是 T 的任何父类型。
import java.util.ArrayList;
import java.util.List;
// 定义一个基础类
class Animal {
public void eat() {
System.out.println("Animal is eating");
}
}
// 定义 Animal 的子类
class Dog extends Animal {
@Override
public void eat() {
System.out.println("Dog is eating");
}
}
// 定义 Dog 的子类
class GoldenRetriever extends Dog {
@Override
public void eat() {
System.out.println("Golden Retriever is eating");
}
}
public class LowerBoundWildcardExample {
public static void addDogs(List<? super Dog> dogList) {
dogList.add(new Dog());
dogList.add(new GoldenRetriever());
// 不能添加 Animal,因为不确定具体的泛型类型是否是 Animal 的父类
// dogList.add(new Animal());
}
public static void main(String[] args) {
List<Dog> dogList = new ArrayList<>();
addDogs(dogList);
List<Animal> animalList = new ArrayList<>();
addDogs(animalList);
for (Object obj : dogList) {
if (obj instanceof Dog) {
((Dog) obj).eat();
}
}
for (Object obj : animalList) {
if (obj instanceof Dog) {
((Dog) obj).eat();
}
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南