1. 程式人生 > >三句話總結JAVA泛型萬用字元(PECS)

三句話總結JAVA泛型萬用字元(PECS)

在JAVA的泛型集合中,預設都可以新增null,除此以外,還有以下三條規則。

1. “?”不能新增元素

以“?”宣告的集合,不能往此集合中新增元素,所以它只能作為生產者(亦即它只能被迭代),如下:

List<?> names = Lists.newArrayList("yiifaa");
//  萬用字元宣告的集合,獲取的元素都是Object型別
List<Object> allNames = Lists.newArrayList("yiifee");
allNames.addAll(names);
//  只能以Object迭代元素
for(Object name: names) {
    System.out.println(name);
}

2. “? extends T”也不能新增元素

以“? extends T”宣告的集合,不能往此集合中新增元素,所以它也只能作為生產者,如下:

List<? extends String> names = Lists.newArrayList("yiifaa");
//  宣告消費者
List<String> allNames = Lists.newArrayList("yiifee");
//  消費生產者的元素
allNames.addAll(allNames);

相對於以“?”宣告的集合,“? extends T”能更輕鬆地迭代元素:

List<? extends String> names = Lists.newArrayList("yiifaa"
); // 能更精確地確認元素型別 for(String name: names) { System.out.println(name); }

3. “? super T”能新增元素

在萬用字元的表示式中,只有“? super T”能新增元素,所以它能作為消費者(消費其他萬用字元集合)。

List<? super String> allNames = Lists.newArrayList("yiifaa");
//
List<String> names = Lists.newArrayList("yiifee");
//  可以直接新增泛型元素
allNames.
addAll(names); // 也可以新增萬用字元泛型元素 List<? extends String> names1 = Lists.newArrayList("yiifee"); allNames.addAll(names1);

針對採用“? super T”萬用字元的集合,對其遍歷時需要多一次轉型,如下:

//  只能獲取到Object型別
for(Object name: allNames) {
    //  這裡需要一次轉型
    System.out.println(name);
}

結論

JAVA泛型萬用字元的使用規則就是赫赫有名的“PECS”(生產者使用“? extends T”萬用字元,消費者使用“? super T”萬用字元)。