欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【Java泛型】泛型通配符?

程序员文章站 2024-03-14 23:10:29
...

1. 泛型通配符?

List<?>是任何泛型List的父类型,所以您完全可以将 List<Object>List<Integer> List<List<List<String>>>传递给printList()

public class Wildcard {

    public static void main(String[] args) {
        // Integer
        List<Integer> integer = new ArrayList<Integer>();
        integer.add(new Integer(0));
        integer.add(new Integer(1));
        // String
        List<String> str = new ArrayList<String>();
        str.add(new String("Hello"));
        str.add(new String("World"));
        // Person
        List<Person> pList = new ArrayList<Person>();
        pList.add(new Person(11, "zhang,san"));
        pList.add(new Person(22, "li,si"));

        List<List<String>> allNameList = new ArrayList<List<String>>();
        for (Person person : pList) {
            List<String> namelist = person.getNameList();
            allNameList.add(namelist);
        }
        System.out.println("==========Integer==========");
        printList(integer);
        System.out.println("==========String==========");
        printList(str);
        System.out.println("==========Pojo==========");
        printList(pList);
        System.out.println("==========List<List<String>>==========");
        printList(allNameList);

    }

    static void printList(List<?> l) {
        for (Object o : l) {
            System.out.println(o);
        }
    }
}

class Person {

    private int          age;
    private String       name;
    private List<String> nameList;

    public Person(int age, String name){
        this.age = age;
        this.name = name;
        initNames();
    }

    private void initNames() {
        String[] nameArr = this.name.split(":");
        for (String str : nameArr) {
            if (this.nameList == null) {
                this.nameList = new ArrayList<String>();
            }
            this.nameList.add(str);
        }
    }

    public List<String> getNameList() {
        return nameList;
    }

    public void setNameList(List<String> nameList) {
        this.nameList = nameList;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
    }
}
 

 

 


2. 通篇符add操作限制

 

对于上述的List<?>可以从中方便的检索元素,但是不能添加 元素(可以添加null):

 

        List<?> wildList = integer;
        wildList.add(null);
        // 对于luu,编译器不能对List的类型参数作出足够严密的推理,以确定将Integer传递给List.add()是类型安全的。所以编译器将不允许您这么做。
        wildList.add(new Integer(3)); // wrong
        // 以免您仍然认为编译器知道哪些方法更改列表的内容哪些不更改列表内容,请注意下面的代码将能工作,因为它不依赖于编译器必须知道关于lu的类型参数的任何信息
        wildList.remove(1);
        wildList.clear();
 

3. ? extends 和 ? super

 

上面add操作的限制,同样适用于List<? extends Number>这种情况,上限是Number,故不能确定到底添加的是神马类型的数据

但是可用于List<? super Integer>这样情况,下限是Integer,明确添加的数据是Integer或Integer的子类

public class ExtendAndSuper {

    public static void main(String[] args) {

        List<Integer> intList = new ArrayList<Integer>();
        intList.add(1);
        intList.add(2);
        List<Number> numList = new ArrayList<Number>();
        numList.add(1);
        numList.add(2);

        List<? extends Number> numWild1 = intList;   //extends
        System.out.println(numWild1.get(0));
        // numWild.add(3); //wrong        
        // 需要强制转换,但不安全
        List<Integer> myIntList = (List<Integer>) numWild1;
        myIntList.add(3);
        List<? super Integer> numWild2 = intList;   //super
        numWild2.add(3);
        System.out.println(numWild1.get(2));
        List<? super Number> numWild3 = numList;
        numWild3.add(new Float(3.14));
        System.out.println(numWild3.get(2));
        
            
        List<? extends Number> numExtend = new ArrayList<Number>();
        // numExtend.add(3);//wrong
        List<? super Number> numSuper = new ArrayList<Number>();
        numSuper.add(3);
        numSuper.add(new Float(3.14));
    }
}