zoukankan      html  css  js  c++  java
  • 87.Java泛型通配符

    泛型通配符

    需求:

    定义一个方法,接收一个集合对象(该集合有泛型),并打印出集合中的所有元素。

    例如集合对象如下格式:

    Collection<Person> coll = new ArrayList<Person>();
            coll.add(new Person("jack", 20));
            coll.add(new Person("rose", 18));
            Collection<Object> coll2 = new ArrayList<Object>();
            coll2.add(new Object());
            coll2.add(new Object());
            coll2.add(new Object());
    
            Collection<String> coll3 = new ArrayList<String>();
            coll3.add("abc");
            coll3.add("ddd");
            coll3.add("eee");

    分析,集合对象中的元素的类型是变化的,方法的形参的那么泛型类型就只能定义为Object类型.

    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.HashSet;
    import java.util.Iterator;
    
    public class Demo9 {
        public static void main(String[] args) {
            ArrayList<Object> arr = new ArrayList<Object>();
            arr.add(new Object());
            arr.add("String");
            print(arr);
            
            //将集合的泛型设置类String类型,是Object子类
            HashSet<String> hs = new HashSet<String>();
            hs.add("hello");
            hs.add("jack");
            //由于print方法接收的集合进行了元素限定,只接受限定为Object类型的集合,编译不通过
            //print(hs);
        }
    
        public static void print(Collection<Object> coll) {
            Iterator<Object> it = coll.iterator();
            while (it.hasNext()) {
                Object next = it.next();
                System.out.println(next);
            }
        }
    }

    但是,由于print方法接收的集合进行了元素限定,只接受限定为Object类型的集合,编译不通过该问题如何解决?

    可以把方法的形参的泛型去掉,那么方法中就把集合中的元素当做Object类型处理.

    也可以使用使用泛型通配符

    public class Demo9 {
        public static void main(String[] args) {
            ArrayList<Object> arr = new ArrayList<Object>();
            arr.add(new Object());
            arr.add("String");
            print(arr);
    
            // 将集合的泛型设置类String类型,是Object子类
            HashSet<String> hs = new HashSet<String>();
            hs.add("hello");
            hs.add("jack");
            // 使用泛型通配符,编译通过。
            print(hs);
        }
    
        public static void print(Collection<?> coll) {
            Iterator<?> it = coll.iterator();
            while (it.hasNext()) {
    
                Object next = it.next();
                System.out.println(next);
            }
        }
    }

    上述就使用了泛型通配符

    通配符:?
    public void show(List<?> list)
    {
    }
    可以对类型进行限定范围。
    ?extends E: 接收E类型或者E的子类型。
    ? super E: 接收E类型或者E的父类型。

    限定泛型通配符的边界

    限定通配符的上边界:

    extends

    接收Number 类型或者Number的子类型

    正确:Vector<? extends Number> x = new Vector<Integer>();
    错误:Vector<? extends Number> x = new Vector<String>();

    限定通配符的下边界

    super

    接收Integer 或者Integer的父类型

    正确:Vector<? super Integer> x = new Vector<Number>();
    错误:Vector<? super Integer> x = new Vector<Byte>();

    总结:

    JDK5中的泛型允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定

    注意:泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。

    泛型的基本术语,以ArrayList<E>为例:<>念着typeof

    ArrayList<E>中的E称为类型参数变量

    ArrayList<Integer>中的Integer称为实际类型参数

    整个称为ArrayList<E>泛型类型

    整个ArrayList<Integer>称为参数化的类型ParameterizedType

    author@nohert
  • 相关阅读:
    睡前一分钟打造完美下半身 健康程序员,至尚生活!
    几种不伤身体的速效减肥秘方 健康程序员,至尚生活!
    头发一周洗几次才适宜? 健康程序员,至尚生活!
    夏日驱蚊虫蟑螂的最好办法! 健康程序员,至尚生活!
    WPF控件和布局
    《深入浅出WPF》笔记——绑定篇(二)
    WPF中的DataTemplate绑定使用的场合
    WPF第一个程序和XAML初探
    实习总结之jquery实例
    下一步要实战的东西
  • 原文地址:https://www.cnblogs.com/gzgBlog/p/13623841.html
Copyright © 2011-2022 走看看