`
Phoenix_MVP
  • 浏览: 338133 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

【Java泛型】泛型通配符?

    博客分类:
  • Java
 
阅读更多

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));
    }
}
 

 

 

 

 

分享到:
评论

相关推荐

    详谈Java泛型中T和问号(通配符)的区别

    Java泛型中T和问号(通配符)的区别 Java泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、...

    Java泛型通配符

    Java泛型通配符是Java编程语言中一个重要的特性,它允许我们在定义泛型类型时使用问号(?)作为占位符,表示任意类型的参数。这种通配符的使用大大提高了代码的灵活性和可复用性,同时也帮助开发者遵循强类型检查的...

    Java泛型三篇文章,让你彻底理解泛型(super ,extend等区别)

    接下来,让我们详细讨论 Java 泛型的关键字和通配符。 extends 和 super 的区别 在 Java 泛型中,extends 和 super 是两个重要的关键字,它们分别用于限定类型的上界和下界。 extends 用于限定类型的上界,表示...

    泛型讲解 类型通配符

    "泛型讲解 类型通配符" 泛型是Java语言中的一种机制,它允许在定义类、接口时指定类型形参,这个类型形参将在声明变量、创建对象时确定。泛型的引入解决了Java集合的缺陷,即集合会“忘记”对象的类型,导致...

    Java泛型应用实例

    Java泛型是Java编程语言中的一个强大特性,它允许我们在定义类、接口和方法时指定类型参数,从而实现代码的重用和类型安全。在Java泛型应用实例中,我们可以看到泛型如何帮助我们提高代码的灵活性和效率,减少运行时...

    java泛型技术之发展

    Java泛型技术是Java编程语言中的一个重要特性,它在2004年随着Java SE 5.0的发布而引入,极大地增强了代码的类型安全性和可读性。本篇文章将深入探讨Java泛型的发展历程、核心概念以及其在实际开发中的应用。 一、...

    java 泛型接口示例

    Java 泛型是Java SE 5.0引入的一项重要特性,极大地增强了代码的类型安全性和重用性。泛型接口是泛型在接口中的应用,它允许我们在接口中定义带有类型参数的方法,使得实现该接口的类可以使用不同的数据类型。下面...

    java 泛型方法使用示例

    Java 泛型是Java SE 5.0引入的一项重要特性,极大地增强了代码的类型安全性和重用性。泛型方法是泛型技术在类方法层面的应用,它允许我们定义一个可以处理多种数据类型的通用方法。下面我们将深入探讨Java泛型方法的...

    Java 泛型通配符的一个实例

    * 一个参数通配符的实例 * 说明:对一个包含了数值元素的集合进行汇总运算。在这种情况下,用户并不关心 * 集合中的每一个对象是什么类型,只要它是数值型即可,而且,用户也希望集合中可以 * 存放不同类型的数值...

    java泛型的内部原理及更深应用

    Java泛型是Java编程语言中的一个强大特性,它允许在定义类、接口和方法时使用类型参数,从而实现参数化类型。这使得代码更加安全、可读性更强,并且能够减少类型转换的必要。在“java泛型的内部原理及更深应用”这个...

    SUN公司Java泛型编程文档

    6. **基本类型与泛型**:Java泛型不支持原始类型(如int、char)作为类型参数,但可以通过使用专门的通配符如`Integer[]`或`? extends Number`来间接实现。 7. **泛型和多态**:泛型类可以作为其他泛型类或非泛型类...

    关于java基础的泛型的练习

    - 泛型通配符:例如`?`,表示任意类型。`List&lt;?&gt;`表示可以容纳任何类型的列表。 - 上界通配符:`&lt;? extends T&gt;`限制了只能传入T或T的子类类型的对象。 - 下界通配符:`&lt;? super T&gt;`限制了只能传入T或T的父类类型...

    Java泛型技术之发展.pdf

    Java泛型是Java编程语言中的一个关键特性,它在2004年随着Java SE 5.0的发布而引入,极大地增强了代码的类型安全性和重用性。本篇文章将深入探讨Java泛型的发展历程、核心概念以及其在实际开发中的应用。 1. **发展...

    java泛型Demo

    Java泛型是Java编程语言中的一个关键特性,它在2004年随着JDK 5.0的发布被引入。泛型的主要目的是提供类型安全,帮助程序员在编译时发现可能的类型错误,同时也提供了更好的代码重用。在这个"java泛型Demo"中,我们...

    关于C#、java泛型的看法

    这意味着Java的泛型不支持协变和逆变,但可以通过通配符(如?)来放宽类型限制。Java的泛型约束则相对较少,主要通过extends和super关键字来限制类型参数的范围。 在实际应用中,C#的泛型在效率上可能具有优势,...

    Java泛型编程最全总结

    Java泛型还有通配符,用于表示对类型的限制。例如,`?`表示任何类型,`? extends Number`表示任何Number的子类,这在处理多种类型集合时非常有用。比如,`accept(List&lt;? extends Number&gt;)`可以接收`List&lt;Integer&gt;`、...

    Java泛型总结(2)进阶篇

    在本文中,我们将深入探讨Java泛型的进阶概念,包括通配符、边界、类型擦除以及在实际开发中的应用。 1. 通配符 通配符在Java泛型中扮演着重要角色,它允许我们处理多种类型的参数。例如,`&lt;?&gt;` 表示未知类型,...

    java 泛型入门 实例

    Java泛型是Java编程语言中的一个关键特性,它在2004年随着JDK 5.0的发布被引入,极大地增强了代码的类型安全性和重用性。本篇文章将带你入门Java泛型,通过实例深入理解其核心概念。 1. **泛型的基本概念** - 泛型...

    Java 泛型最全指南(定义和使用+继承泛型类/实现泛型接口+泛型的边界+通配符+类型擦除)

    Java 泛型详解 Java 泛型是 Java 5 中引入的一种编程技术,旨在提高代码的复用性和类型安全性。泛型允许开发者编写出“非特定类型”的代码,能够根据实际情况选择合适的类型,从而提高代码的灵活性和可维护性。 1....

Global site tag (gtag.js) - Google Analytics