2025年JAVA中的泛型与PECS 原则

JAVA中的泛型与PECS 原则PECS 原则 在使用限定通配符 bounded wildcard 时 需要遵守 PECS 原则 PECS 是 Producer Extends Consumer Super 的缩写 是一种设计原则 用于指导使用泛型类型和限定通配符时的编程风格 PECS 原则的核心思想是 Producer 使用

大家好,我是讯享网,很高兴认识大家。

PECS 原则

在使用限定通配符(bounded wildcard)时,需要遵守 PECS 原则。PECS 是 Producer-Extends, Consumer-Super 的缩写,是一种设计原则,用于指导使用泛型类型和限定通配符时的编程风格。

PECS 原则的核心思想是:Producer 使用 extends 通配符,Consumer 使用 super 通配符。

当泛型类型只用于产生(读取)元素时,即作为生产者时,使用 ? extends T 形式的限定通配符。这表示可以接受 T 或 T 的子类型。通过使用 extends,我们可以从集合中安全地获取元素,因为我们只关心元素的上界,而不关心具体的子类型。

当泛型类型只用于消费(写入)元素时,即作为消费者时,使用 ? super T 形式的限定通配符。这表示可以接受 T 或 T 的超类型。通过使用 super,我们可以向集合中安全地添加元素,因为元素一定是 T 或 T 的父类型。

通过遵循 PECS 原则,可以确保泛型在多态的使用中具有更灵活和安全的行为。下面是一些示例:

作为生产者使用 ? extends T:

public void process(List<? extends Animal> animals) { 
    for (Animal animal : animals) { 
    animal.eat(); } } 

讯享网

在上述例子中,List<? extends Animal> 可以接受 Animal 或 Animal 的子类型的集合。我们只关心元素是 Animal 或其子类型,因此可以安全地读取元素。

c作为消费者使用 ? super T:

讯享网public void feed(List<? super Dog> dogs) { 
    dogs.add(new Dog()); dogs.add(new Puppy()); } 

在上述例子中,List<? super Dog> 可以接受 Dog 或 Dog 的父类型的集合。我们可以添加 Dog 或其子类型的实例到集合中,因为集合的元素至少是 Dog。但如果使用 List<? extends Dog>,则无法添加元素,因为无法确定元素的类型。


讯享网

通过遵循 PECS 原则,可以确保代码更加灵活、类型安全,并且在处理泛型集合时提供更好的扩展性和适应性。

T extends Animal 和 ? extends Animal 之间的差别

T extends Animal 是一个泛型声明,它将类型参数 T 限定为 Animal 或 Animal 的子类型。这意味着我们在使用这个泛型类型时,可以指定具体的类型参数,例如 List< Dog >、List< Cat >

而 ? extends Animal 是一个通配符表达式,用于限定通配符类型。它表示可以接受任何 Animal 或 Animal 的子类型的实例。通配符类型一般用于方法的参数或返回类型中,以表示方法对具体类型的灵活性。

在使用上,T extends Animal 允许在编译时具体指定类型参数,而 ? extends Animal 只能接受一种未知类型的 Animal 或 Animal 的子类型。这意味着 ? extends Animal 可能更加灵活,因为它可以接受更多可能的类型参数。

下面是一些具体的示例,来说明两者之间的差别:

// 泛型声明 class SomeClass<T extends Animal> { 
    // 使用具体的类型参数 private List<T> animals; public SomeClass() { 
    animals = new ArrayList<>(); } public void addAnimal(T animal) { 
    animals.add(animal); } public T getAnimal(int index) { 
    return animals.get(index); } } // 通配符 void processAnimals(List<? extends Animal> animals) { 
    for (Animal animal : animals) { 
    animal.eat(); } } public static void main(String[] args) { 
    // 使用泛型声明 SomeClass<Dog> dogClass = new SomeClass<>(); dogClass.addAnimal(new Dog()); dogClass.addAnimal(new Puppy()); // 是 Dog 的子类型,可以用于 T extends Animal Dog dog = dogClass.getAnimal(0); // 使用通配符类型 List<Dog> dogs = new ArrayList<>(); dogs.add(new Dog()); dogs.add(new Puppy()); processAnimals(dogs); // 可以匹配 ? extends Animal } 

总结来说,T extends Animal 是一种具体的类型参数限定,而 ? extends Animal 是一种灵活的通配符类型限定。根据具体需求,你可以选择使用其中之一来实现不同的泛型行为。

小讯
上一篇 2025-04-06 15:32
下一篇 2025-02-17 20:58

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/42215.html