美文网首页
泛型通配符

泛型通配符

作者: code希必地 | 来源:发表于2020-10-13 16:16 被阅读0次

1、无边界通配符

这里先看个例子:定义一个泛型类

public class Point<T> {

    private T x;
    private T y;

    public Point(T x, T y) {
        this.x = x;
        this.y = y;
    }

    public T getX() {
        return x;
    }

    public void setX(T x) {
        this.x = x;
    }

    public T getY() {
        return y;
    }

    public void setY(T y) {
        this.y = y;
    }
}

泛型类的使用如下:

public void test() {
        Point<Integer> intPoint = new Point<>(12, 12);
        Point<Float> floatPoint = new Point<>(12.0f, 12.0f);
    }

可以看到我们创建了泛型类型为Integer、Float两个实例intPoint 和floatPoint ,如果生成n个类型的实例,就需要创建n个变量,那能不能只创建一个变量呢?

public void test2() {
        Point<?> point;
        point = new Point<Integer>(12, 12);
        point = new Point<Float>(12.0f, 12.0f);
    }

这里使用了无边界通配符?来实现只创建一个变量的功能,无边界通配符?只能用于填充泛型变量T,?表示可通配任意类型。下面再看个实例:

public void test() {
        List<String> list1=new ArrayList<>();
        List<Integer> list2=new ArrayList<>();

        test2(list1); //编译失败
        test2(list2); //编译失败
    }

    public void test2(List<Object> list) {

    }

test2()函数接收的是一个List<Object>类型的变量,向其中传入List<String>和List<Integer>都是编译不通过的,这里我们使用通配符修改下test2()编译就能通过了

public void test2(List<?> list) {
}

2、通配符 <? extends XXX>

通配符 <? extends XXX>是指在填充泛型T的类型为XXX的子类并且包括XXX本身,看下具体的使用

 public void test() {
        List<String> list1=new ArrayList<>();
        List<Integer> list2=new ArrayList<>();
        List<Number>  list3=new ArrayList<>();
       
        test2(list1);//编译失败
        test2(list2);
        test2(list3);
    }

    public void test2(List<? extends Number> list) {
    }

这里使用<? extends Number>限定泛型的填充类型为Number的子类或Number,由于String并不是Number类型也不是其子类,所以编译失败。
使用<? extends Number>定义的变量,只能取其中的值,却不能修改

public void test2(List<? extends Number> list) {
        list.add(12); //编译失败
        Number number = list.get(0); //编译成功
    }

上面代码我们无法通过add添加数据,但是能通过get()来取出数据,这又是为什么呢?

使用<? extends Number>表示填充泛型类型为Number及其子类型未知类型,因为不确定类型,所以不能通过add进行修改数据。
但是可以确定的是通过get()取出的类型一定是Number类型的。

3、通配符<? super XXX>

<? extends XXX>表示填充泛型类型为任意XXX子类的类型,<? super XXX>表示填充为任意XXX的父类。

public class Person {
    }

    public class Man extends Person {
    }

    public class Teacher extends Man {
    }


    public void test() {
        List<Person> list1 = new ArrayList<>();
        List<Man> list2 = new ArrayList<>();
        List<Teacher> list3 = new ArrayList<>();

        test2(list1);
        test2(list2);
        test2(list3); //编译失败
    }

    public void test2(List<? super Man> list) {

    }

由于<? super Man>表示填充泛型类型为Man及其Man的父类的类型,而Teacher是Man的子类,所以编译失败。
<? super Man>定义的变量能存不能取

public void test2(List<? super Man> list) {
        Man man=new Man();
        list.add(man);

        Teacher teacher=new Teacher();
        list.add(teacher);

        Person person=new Person();
        list.add(person);//编译失败
    }

<? super Man>填充的类型为Man以及Man的父类的类型,所以当添加的数据为Man或者其子类类型的数据时,肯定是没问题的。而当添加的数据为Man的父类时则编译不通过,比如此时test2()函数传入的类型是List<Man>时,list.add(person);是会报错的。
list.get(0);编译是不会报错的,但是通过get()取出的数据类型是不确定的,所以单纯的取出是没有什么意义的。

相关文章

  • Android 学习(一):Java 泛型

    Java泛型学习 1.0 泛型常用案例 2.0 泛型方法 3.0 泛型类 4.0 通配符 ? 通配符,占位符,标识...

  • Kotlin泛型方法

    泛型约束 泛型通配符

  • Java-API-集合框架(三)-泛型

    泛型的由来和基本使用 泛型的擦除 泛型类的使用 泛型方法的使用 泛型接口 泛型通配符(?) 通配符? 在api中的...

  • java 泛型通配符和边界

    1. 通配符 泛型中常用的通配符: 我们在定义泛型类,泛型方法,泛型接口的时候经常会碰见很多不同的通配符,比如 T...

  • Java泛型

    1. 泛型通配符与PECS 为什么要使用泛型通配符和边界 List泛型转换需要用到通配符 ? “装A的List” ...

  • 注解

    作用: 在类中定义泛型: 在方法中定义泛型: 给泛型设置通配符上限: 给泛型设置通配符下限: 泛型擦除: 兼容性:...

  • Java中通配符的范围上限与范围下限

    泛型中通配符 我们在定义泛型类,泛型方法,泛型接口的时候经常会碰见很多不同的通配符,比如 T,E,K,V 等等,这...

  • java基础

    八、泛型 面试题==什么是泛型中的限定通配符和非限定通配符 ?这是另一个非常流行的Java泛型面试题。限定通配符对...

  • 泛型机制(二)

    泛型通配符 实例代码 结果 泛型的上下限限定 定义

  • java基础知识梳理&泛型初探

    目录 概述 范型的使用 类型参数 类型通配符 泛型方法 泛型类 限定类型参数上限 上界通配符(Upper Boun...

网友评论

      本文标题:泛型通配符

      本文链接:https://www.haomeiwen.com/subject/rchvpktx.html