面试题答案
一键面试区别
- 上界通配符<? extends T>
- 表示类型的上界,即该通配符代表的类型是T或者T的子类。
- 可以读取集合元素,但写入时受限,只能写入null。因为编译器无法确定具体的子类型,所以除了null,写入任何其他对象都可能导致类型不匹配。
- 下界通配符<? super T>
- 表示类型的下界,即该通配符代表的类型是T或者T的超类。
- 可以写入元素,因为T及其子类对象都可以安全地赋值给T的超类类型。但读取时受限,只能将读取的元素赋值给Object类型(因为具体超类类型不确定)。
适用场景
- 上界通配符<? extends T>
- 适用于只需要从集合中读取数据的场景。例如,计算集合中元素的总和、平均值等操作。
- 下界通配符<? super T>
- 适用于只需要向集合中写入数据的场景。例如,将一组特定类型的元素添加到集合中。
代码示例
- 上界通配符<? extends T>在方法参数中的使用
import java.util.ArrayList;
import java.util.List;
class Shape {}
class Circle extends Shape {}
class Rectangle extends Shape {}
public class UpperBoundWildcardExample {
public static double calculateAreaSum(List<? extends Shape> shapes) {
double sum = 0;
for (Shape shape : shapes) {
// 假设Shape有getArea方法
sum += shape.getArea();
}
return sum;
}
public static void main(String[] args) {
List<Circle> circles = new ArrayList<>();
circles.add(new Circle());
double circleAreaSum = calculateAreaSum(circles);
List<Rectangle> rectangles = new ArrayList<>();
rectangles.add(new Rectangle());
double rectangleAreaSum = calculateAreaSum(rectangles);
}
}
- 下界通配符<? super T>在方法参数中的使用
import java.util.ArrayList;
import java.util.List;
class Animal {}
class Dog extends Animal {}
class GoldenRetriever extends Dog {}
public class LowerBoundWildcardExample {
public static void addDogs(List<? super Dog> dogsList, Dog dog) {
dogsList.add(dog);
}
public static void main(String[] args) {
List<Dog> dogs = new ArrayList<>();
addDogs(dogs, new GoldenRetriever());
List<Animal> animals = new ArrayList<>();
addDogs(animals, new Dog());
}
}
- 返回值场景
- 上界通配符返回值示例:
import java.util.ArrayList;
import java.util.List;
class Fruit {}
class Apple extends Fruit {}
public class UpperBoundReturnExample {
public static List<? extends Fruit> getApples() {
List<Apple> apples = new ArrayList<>();
apples.add(new Apple());
return apples;
}
public static void main(String[] args) {
List<? extends Fruit> fruits = getApples();
for (Fruit fruit : fruits) {
// 处理水果
}
}
}
- **下界通配符返回值示例**:虽然使用较少,但如果有这样的需求,如下:
import java.util.ArrayList;
import java.util.List;
class Plant {}
class Flower extends Plant {}
class Rose extends Flower {}
public class LowerBoundReturnExample {
public static List<? super Rose> getRoseContainer() {
List<Flower> flowers = new ArrayList<>();
return flowers;
}
public static void main(String[] args) {
List<? super Rose> roseContainer = getRoseContainer();
roseContainer.add(new Rose());
}
}
通过上述示例,可以看到如何在不同场景中正确使用上界和下界通配符,实现灵活且类型安全的集合操作。