深入Java 泛型(二:通配符与上下边界)

一 .泛型中通配符

1) 常用的 T,E,K,V等泛型字母为有类型,类型参数赋予具体的值

2) 无界通配符  ?  未知类型  类型参数赋予不确定值,任意类型

3) 上界通配符 < ? extends E>

4) 下界通配符 < ? super E>

二.通配符与上下边界

(1)无界类型通配符和泛型方法差不多,只是不用在使用前进行定义,例子如下:

public void processElements(List<?> elements){
   for(Object o : elements){
      System.out.println(o);
   }
}

"?"可以接收任何类型。


(2)上界通配符 < ? extends E>

//这种情况下能够接收A类或者A类的子类。
public void processElements(List<? extends A> elements){
   for(A a : elements){
      System.out.println(a.getValue());
   }
}

// 上边界通配符直接使用add()方法受限,但是可以用来获取各种数据类型的数据,
// 并赋值给父类型的引用。
List<? extends Number> list=new ArrayList<Integer>();
list.add(new Integer(1));//报错,因为list不能确定实例化的对象具体类型导致add()方法受限
...
list.get(0);//正确

  正确用法:



import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        firstPrint();
        secondPrint();
    }

    public static void firstPrint() {
        List<Float> list1 = new ArrayList<>();//使用 Float作实参类型
        list1.add(12.3f);
        list1.add(23.4f);
        print(list1);
    }

    public static void secondPrint() {
        List<Integer> list2 = new ArrayList<>();//使用Integer作实参类型
        list2.add(1);
        list2.add(2);
        list2.add(3);
        print(list2);
    }

    public static void print(List<? extends Number> list) {// 通配符作形参
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));// 使用get方法
        }
    }
}


(3)下界

//这种情况下能够接收A类或者A类的父类
public static void insertElements(List<? super A> list){
    list.add(new A());
    list.add(new B());
    list.add(new C());
}

//下边界通配符使用get()方法受限(不使用强转),但是可以添加特定类型的值,
//用于将对象写入到一个数据结构里
List<? super Integer> list = new ArrayList<Number>();
list.add(1);
Number number = list.get(0);//报错,因为List<? super Integer>不知道list存放的对象具体类型,则使用get获取到的值不确定。
...
list.add(1);//正确

  正确用法:


import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Number> list = new ArrayList<>();
        firstInflate(list);
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        list.clear();
        secondInflate(list);
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }

    public static void firstInflate(List<? super Integer> list) {// 装填整数
        list.add(1);
        list.add(2);
        list.add(3);
    }

    public static void secondInflate(List<? super Float> list) {// 装填浮点数
        list.add(1.1f);
        list.add(2.2f);
        list.add(1.3f);
    }
}

三.?和 T 的区别

?是通配符(占位符),可以表示任意一个,T只是一种替代,只能表示其中一个

假设有A,B,C三个类

<?>可以是A,B,C任意一个,每一个<?>之间没有关联

<T>如果确定了是A那之后的都是A,每一个<T>代表的是相同的

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值