MST

星途 面试题库

面试题:Java泛型下限通配符与上限通配符的区别及应用场景分析

阐述Java泛型中下限通配符(? super)和上限通配符(? extends)的区别。请分别举例说明在实际项目中,下限通配符和上限通配符在集合操作、方法参数传递等方面的具体应用场景,以及为什么要使用它们来解决特定的问题。
35.1万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

1. 上限通配符(? extends)

  • 定义:表示类型的上界,即该通配符可以匹配指定类型及其所有子类型。
  • 集合操作示例
import java.util.ArrayList;
import java.util.List;

class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}

public class UpperBoundExample {
    public static void main(String[] args) {
        List<Dog> dogList = new ArrayList<>();
        dogList.add(new Dog());
        printAnimals(dogList);

        List<Cat> catList = new ArrayList<>();
        catList.add(new Cat());
        printAnimals(catList);
    }

    public static void printAnimals(List<? extends Animal> list) {
        for (Animal animal : list) {
            System.out.println(animal);
        }
    }
}
  • 方法参数传递应用场景:当方法只需要读取集合中的元素,而不需要添加元素时,使用上限通配符。因为此时可以接受任何包含Animal及其子类型对象的集合,提高了代码的通用性。例如上述printAnimals方法,它不关心具体是Dog还是Cat集合,只要是Animal及其子类型的集合都能处理。

2. 下限通配符(? super)

  • 定义:表示类型的下界,即该通配符可以匹配指定类型及其所有父类型。
  • 集合操作示例
import java.util.ArrayList;
import java.util.List;

class Animal {}
class Dog extends Animal {}
class GoldenRetriever extends Dog {}

public class LowerBoundExample {
    public static void main(String[] args) {
        List<Animal> animalList = new ArrayList<>();
        addDogs(animalList);

        List<Dog> dogList = new ArrayList<>();
        addDogs(dogList);
    }

    public static void addDogs(List<? super Dog> list) {
        list.add(new Dog());
        list.add(new GoldenRetriever());
    }
}
  • 方法参数传递应用场景:当方法需要向集合中添加元素,并且希望能够接受指定类型及其父类型的集合时,使用下限通配符。比如上述addDogs方法,它可以向AnimalDog类型的集合中添加Dog及其子类型对象,确保了类型安全并且增加了方法的灵活性。

3. 总结区别

  • 上限通配符(? extends):主要用于读取数据,因为它能接受指定类型及其子类型的集合,但由于无法确切知道集合的具体类型,所以一般不能向集合中添加元素(除了null)。
  • 下限通配符(? super):主要用于写入数据,它能接受指定类型及其父类型的集合,使得可以安全地向集合中添加指定类型及其子类型的元素。