MST

星途 面试题库

面试题:Java数据结构中泛型的边界与通配符

在Java中,假设你要实现一个方法,该方法接收一个包含某种类型数据的列表,并对列表中的元素进行特定操作,但要求该方法既能接受该类型及其子类类型的列表。请使用泛型的上界通配符实现这个方法,并解释为什么使用上界通配符而不是直接使用泛型类型。另外,说明在这种场景下,如果使用下界通配符会有什么不同的效果。
23.0万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

以下是使用泛型上界通配符实现该方法的Java代码示例:

import java.util.List;

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

public class GenericExample {
    public static void performOperation(List<? extends Animal> list) {
        for (Animal animal : list) {
            // 对列表中的元素进行特定操作,这里简单打印
            System.out.println(animal);
        }
    }
}

为什么使用上界通配符而不是直接使用泛型类型

  1. 灵活性:如果直接使用泛型类型,比如 public static <T> void performOperation(List<T> list),方法只能接受具体类型 T 的列表,无法接受 T 子类类型的列表。而使用上界通配符 <? extends Animal>,方法可以接受 Animal 及其子类(如 DogCat)类型的列表,提高了方法的通用性。
  2. 类型安全:上界通配符确保在方法内部操作的元素都是 Animal 或其子类,从而保证类型安全。

使用下界通配符的不同效果

如果使用下界通配符,代码如下:

public static void performOperation(List<? super Animal> list) {
    // 注意这里添加元素的限制
    list.add(new Animal());
    list.add(new Dog());
    list.add(new Cat());
    for (Object obj : list) {
        System.out.println(obj);
    }
}
  1. 添加元素:使用下界通配符 <? super Animal> 时,方法内部可以向列表中添加 Animal 及其子类的对象。因为 list 至少是 Animal 类型的列表,所以添加 Animal 及其子类是安全的。
  2. 读取元素:在读取列表元素时,由于不知道列表实际存储的具体类型,只能使用 Object 类型来接收。这可能会导致在后续操作中需要进行类型转换,增加了类型转换异常的风险。而下界通配符的主要目的是在向集合中插入元素时保证类型安全,而不是方便读取元素。

总结来说,上界通配符更侧重于安全地读取数据,而下界通配符更侧重于安全地写入数据。根据具体需求选择合适的通配符可以提高代码的灵活性和类型安全性。