MST
星途 面试题库

面试题:Java泛型中的通配符有哪些,各自的作用是什么

在Java泛型编程里,通配符是很重要的概念。请详细阐述Java泛型中通配符的种类,并举例说明每种通配符在实际代码中的作用及适用场景。
39.6万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

在Java泛型中,通配符主要有以下几种:

无界通配符 <?>

  • 作用:表示可以匹配任何类型。使用无界通配符时,只能调用对象中与类型参数无关的方法,不能调用修改泛型类型参数的方法。
  • 适用场景:当你只需要读取集合中的元素,而不关心元素的具体类型,且不需要修改集合时适用。
  • 示例
import java.util.ArrayList;
import java.util.List;

public class UnboundedWildcardExample {
    public static void printList(List<?> list) {
        for (Object element : list) {
            System.out.print(element + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        List<Integer> intList = new ArrayList<>();
        intList.add(1);
        intList.add(2);

        List<String> stringList = new ArrayList<>();
        stringList.add("Hello");
        stringList.add("World");

        printList(intList);
        printList(stringList);
    }
}

上界通配符 <? extends T>

  • 作用:表示类型的上界,即该通配符所代表的类型必须是T类型或者T类型的子类。这种通配符适用于需要读取数据的场景,因为它确保了从集合中读取的元素类型是T或者T的子类。
  • 适用场景:当你需要从集合中读取元素,并且你知道这些元素的类型是某个特定类型的子类型时适用。
  • 示例
import java.util.ArrayList;
import java.util.List;

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

public class UpperBoundedWildcardExample {
    public static double calculateAverage(List<? extends Number> numbers) {
        double sum = 0;
        for (Number number : numbers) {
            sum += number.doubleValue();
        }
        return sum / numbers.size();
    }

    public static void main(String[] args) {
        List<Integer> intList = new ArrayList<>();
        intList.add(1);
        intList.add(2);

        List<Double> doubleList = new ArrayList<>();
        doubleList.add(1.5);
        doubleList.add(2.5);

        System.out.println(calculateAverage(intList));
        System.out.println(calculateAverage(doubleList));
    }
}

下界通配符 <? super T>

  • 作用:表示类型的下界,即该通配符所代表的类型必须是T类型或者T类型的父类。这种通配符适用于需要写入数据的场景,因为它确保了写入集合的元素类型是T或者T的子类。
  • 适用场景:当你需要向集合中写入元素,并且你知道这些元素的类型是某个特定类型的子类型时适用。
  • 示例
import java.util.ArrayList;
import java.util.List;

class Fruit {}
class Apple extends Fruit {}
class RedApple extends Apple {}

public class LowerBoundedWildcardExample {
    public static void addFruit(List<? super Apple> fruits) {
        fruits.add(new Apple());
        fruits.add(new RedApple());
    }

    public static void main(String[] args) {
        List<Apple> appleList = new ArrayList<>();
        List<Fruit> fruitList = new ArrayList<>();

        addFruit(appleList);
        addFruit(fruitList);
    }
}