A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 琥珀88 初级黑马   /  2018-7-26 11:29  /  675 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 琥珀88 于 2018-7-26 15:04 编辑

泛型通配符


1.基本概念
        1.1无边界泛型通配符:就是<?>,比如List<?>.主要作用就是让泛型能够接收未知类型的数据。
        1.2固定上边界泛型通配符:格式<? extends E>,E就是该泛型的上边界,用extends关键字不仅表示继承了父类E的子类,也代这实现了接口E的实                 现类。主要作用是让泛型能够接收指定类及其子类类型的数据。
        1.3固定下边界泛型通配符:格式<? super E>,E就是该泛型的下边界。主要作用是让泛型能够接收指定类及其父类类型的数据。
         注意:1.运用泛型通配符主要是用来接收数据的,不能用来存储数据。
                   2.可以为一个泛型指定上边界或者下边界,但是不能同时指定上下边界。
2.基本使用方法
         2.1无边界泛型通配符的使用,以List集合为例:
                        
[Java] 纯文本查看 复制代码
import java.util.ArrayList;
                          import java.util.List;

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

                          public static void main(String[] args) { 
                          List<String> l1 = new ArrayList<>();
                          l1.add("aa");
                          l1.add("bb");
                          l1.add("cc");

                          printList(l1);
                          List<Integer> l2 = new ArrayList<>();
                          l2.add(11);
                          l2.add(22);
                          l2.add(33);
                          printList(l2);
                          }
                          }
           其实使用List<?>的方式就是父类引用指向子类对象。但是printList方法不能写成
public static void printList(List<Object> list)的形式,因为Object虽然是所有类的父类,但是List<Object>跟其它泛型的List(比如List<String>、List<Number>)不存在继承关系。
            List<?> 不能使用add方法(null除外),也不能使用get方法(Object除外)。因为不确定该List的类型,所以不知道add什么类型的数据,但是null是所有引用数据类型都具有的元素;get也一样因为不知道传入的List是什么类型,所以没办法接收得到的get,但是Object是所有数据类型和的父类,所以只有Object可以接收(父类引用指向子类对象)。
         2.2固定上边界泛型通配符的使用,以List为例:
                           
[Java] 纯文本查看 复制代码
import java.util.Arrays;
import java.util.List;

public class Test {
    public static double sumOfList(List<? extends Number> list) {
        double s = 0.0;
        for (Number n : list) {
            // 注意这里得到的n是其上边界类型的, 也就是Number, 需要将其转换为double.
            s += n.doubleValue();
        }
        return s;
    }
 
    public static void main(String[] args) {
        List<Integer> list1 = Arrays.asList(1, 2, 3, 4);
        System.out.println(sumOfList(list1));
        List<Double> list2 = Arrays.asList(1.1, 2.2, 3.3, 4.4);
        System.out.println(sumOfList(list2));
    }
}

             List<? extends E>不能使用add方法。因为泛型<? extends E>指的是E及其子类,如果E有多个子类,那么在传入的时候就不知道到底是什么类。
                                          对于get方法,可以使用E 类型接收(父类引用指向子类对象)。
            2.3固定下边界泛型通配符的使用,以List为例:
[Java] 纯文本查看 复制代码
import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void addNumbers(List<? super Integer> list) {
        for (int i = 1; i <= 10; i++) {
            list.add(i);
        }
    }

    public static void main(String[] args) {
        List<Object> list1 = new ArrayList<>();
        addNumbers(list1);
        System.out.println(list1);
        List<Number> list2 = new ArrayList<>();
        addNumbers(list2);
        System.out.println(list2);
        List<Double> list3 = new ArrayList<>();
        // addNumbers(list3); // 编译报错
    }
}

           List<? super E>能调用add方法,因为在addNumbers方法中add的元素就是Integer类型,而传入的list不管是什么类型,都是Integer或者Integer父类类型。
                                    不能抵用get方法,原因是传入的类都是Integer或其父类类型,传入的数据类型可能是Integer到Object之间的任何类型,不知道是什么具体类型,所以没办法接收,只能是Object,因为所有类都是Object的子类
      
         

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马