建设工程新工艺网站,做毕设好的网站,商标图案,沧浪手机网站建设方案泛型类型通配符限定 #x1f686;PECS | 类型通配符限定如何使用“? extends T”和“? super T”通配符java源码示例PECS | 类型通配符限定
PECS原则是指在使用泛型时#xff0c;当我们需要传递一个泛型集合时#xff0c;如何选择适当的泛型类型通配符来…
泛型类型通配符限定 PECS | 类型通配符限定如何使用“? extends T”和“? super T”通配符java源码示例PECS | 类型通配符限定
PECS原则是指在使用泛型时当我们需要传递一个泛型集合时如何选择适当的泛型类型通配符来限制集合中元素的类型。
这个原则有两个部分
第一部分“Producer Extends”表示如果一个集合中的元素将被频繁读取而不是修改那么我们应该使用限定类型通配符“? extends T”。这是因为如果我们使用非限定的类型参数 T我们只能够保证集合中的元素是 T 类型而不能保证它们的子类类型。但如果我们使用“? extends T”我们可以确保集合中的元素类型是 T 或其子类因此我们可以安全地从集合中读取元素并使用它们。
第二部分“Consumer Super”表示如果一个集合中的元素将被经常插入而不是读取那么我们应该使用“? super T”通配符。这是因为使用非限定类型参数 T 时我们只能保证集合中的元素类型是 T 或其父类类型而不能保证它们是 T 类型或其子类类型。但如果我们使用“? super T”我们可以安全地将类型为 T 或其子类类型的元素插入到集合中因为这些元素都是 T 类型或其父类类型。
因此PECS原则帮助我们选择适当的泛型类型通配符以确保我们在使用泛型时能够正确地读取或修改集合中的元素从而增强代码的可读性和可维护性。
如何使用“? extends T”和“? super T”通配符
假设我们有一个 Animal 类型和它的两个子类 Dog 和 Cat
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
现在我们有一个方法接受一个 Animal 类型的集合并返回其中最后一个元素。我们可以这样实现该方法
public static T T getLast(ListT list) {if (list.isEmpty()) {return null;} else {return list.get(list.size() - 1);}
}
这个方法可以接受一个 Animal 类型的集合但我们也可以使用限定类型通配符“? extends T”来表示集合中的元素类型是 T 或其子类类型。这样我们就可以调用这个方法来获取一个元素类型为 Dog 或 Cat 的集合的最后一个元素
ListDog dogs Arrays.asList(new Dog(), new Dog());
Dog lastDog getLast(dogs);ListCat cats Arrays.asList(new Cat(), new Cat());
Cat lastCat getLast(cats);
这里使用“? extends T”通配符允许我们将 List 和 List 都传递给 getLast 方法因为它们都是 Animal 类型的子类。
另一个示例是假设我们有一个方法接受一个 Animal 类型的集合和一个 Animal 类型的元素将元素插入集合的最前面
public static void insertFirst(List? super Animal list, Animal animal) {list.add(0, animal);
}
这个方法使用“? super T”通配符表示集合中的元素类型是 T 或其父类类型。这样我们就可以调用这个方法来将一个类型为 Dog 或 Cat 的元素插入到一个类型为 Animal 的集合中
ListAnimal animals new ArrayList();
Dog dog new Dog();
insertFirst(animals, dog);Cat cat new Cat();
insertFirst(animals, cat);
这里使用“? super Animal”通配符允许我们将 Animal、Dog、Cat 都插入到类型为 Animal 的集合中因为它们都是 Animal 类型或其子类类型。
java源码示例
有一些 Java 标准库中的方法使用了“? extends T”和“? super T”通配符同时出现。一个经典的例子是 Collections.copy 方法它将一个集合的内容复制到另一个集合中
public static T void copy(List? super T dest, List? extends T src) {int srcSize src.size();if (srcSize dest.size()) {throw new IndexOutOfBoundsException(Source does not fit in dest);}for (int i 0; i srcSize; i) {dest.set(i, src.get(i));}
}
在这个方法中我们同时使用了“? super T”和“? extends T”通配符因为我们需要同时支持将元素类型为 T 或其子类类型的源集合复制到元素类型为 T 或其父类类型的目标集合中。
通过使用“? extends T”通配符来限制源集合的元素类型我们可以确保源集合中的元素类型是 T 或其子类类型。通过使用“? super T”通配符来限制目标集合的元素类型我们可以确保目标集合中的元素类型是 T 或其父类类型。这样即使源集合的元素类型是目标集合元素类型的子类我们也可以安全地将源集合中的元素复制到目标集合中。
以下是使用 Collections.copy 方法的示例代码 ListAnimal animals new ArrayList(Arrays.asList(new Animal(), new Animal()));
ListDog dogs Arrays.asList(new Dog(), new Dog());
Collections.copy(animals, dogs);
在这个示例中我们将一个元素类型为 Dog 的集合复制到一个元素类型为 Animal 的集合中。由于我们在 copy 方法中使用了“? super T”和“? extends T”通配符所以我们可以正确地将元素类型为 Dog 的集合复制到元素类型为 Animal 的集合中。