IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> java 上界和下界Java 泛型之上界下界通配符 -> 正文阅读

[Java知识库]java 上界和下界Java 泛型之上界下界通配符

Java?泛型之上界下界通配符

Java教程是为JDK 8编写的。本页描述的示例和实践没有利用后续版本中引入的改进。

通配符和子类

如 泛型,继承和子类型中所述,泛型类或接口仅仅因为它们的类型之间存在关系而无关。但是,您可以使用通配符在泛型类或接口之间创建关系。

给定以下两个常规(非泛型)类:

class A { /* ... */ }

class B extends A { /* ... */ }

编写以下代码是合理的:

B b = new B();

A a = b;

此示例显示常规类的继承遵循此子类型规则:如果B扩展A,则类B是类A的子类型。此规则不适用于泛型类型:

List?lb = new ArrayList<>();

List la = lb; //编译时错误

鉴于 Integer 是 Number 的子类型, List 和 List 之间的关系是什么?

c7135e0f5839b88edb9a736616dd92a7.gif?公共父类是

List>

该图表显示 List 和 List 的公共父级是未知类型的 List .

尽管 Integer 是 Number 的子类型,但 List 不是 List 的子类型,实际上,这两种类型不相关。 List 和 List 的公共父是 List> 。

上界(extends)的通配符与下界(super)通配符

上界(extends)的通配符意即 该类的父类中包含或本身是指定类 .

下界(super)通配符意即 该类的子类中包含或本身是指定类 .

为了在这些类之间创建关系以便代码可以通过 List 的元素访问 Number 的方法,请使用上界的通配符:

List extends Integer> intList = new ArrayList<>();

List extends Number> numList = intList; // OK, List是 List< ? extends Number>的子类型

因为 Integer 是 Number 的子类型,而 numList 是 Number 对象的列表,所以 intList (是一个Integer对象列表)和 numList 之间现在存在关系。下图显示了使用上限和下限通配符声明的多个 List 类之间的关系。

019c8863053543366a98500f55b8b899.gif

几个通用List类声明的层次结构。

图表显示 List 是 List extends Integer> 和 List 的子类型。 List extends Integer> 是 List extends Number> 的子类型,它是 List > 的子类型。 List 是 List 和 List extends Number> 的子类型。 List super Number> 是 List super Integer> 的子类型, ft且都是 List> 的子类型。

通配符使用指南

学习使用泛型编程时,更令人困惑的一个方面是确定何时使用上限有界通配符以及何时使用下限有界通配符。本文提供一些设计代码时要遵循的一些准则。

为讨论方便,认为变量具备两个功能:

一个“In”变量

“in”变量向代码提供数据。想象一下带有两个参数的复制方法:copy(src,dest)。该SRC参数提供的数据被复制,因此它是“in”参数。

一个“Out”变量

“out”变量保存数据以供其他地方使用。在复制示例中,copy(src,dest),dest参数接受数据,因此它是“out”参数。

当然,一些变量既用于“in”又用于“out”目的 - 这种情况也在本文中也用到了。

在决定是否使用通配符以及适合使用哪种类型的通配符时,可以使用“in”和“out”原则。以下列表提供了遵循的准则:

通配符指南:

extends

super

Object

这些指南不适用于方法的返回类型。应该避免使用通配符作为返回类型,因为它强制 程序员 使用代码来处理通配符。

List extends ...> 可以被非正式地认为是只读的,但这不是一个严格的保证。假设您有以下两个类:

class NaturalNumber {undefined

private int i;

public NaturalNumber(int i) { this.i = i; }

// ...

}

class EvenNumber extends NaturalNumber {undefined

public EvenNumber(int i) { super(i); }

// ...

}

请考虑以下代码:

List le = new ArrayList<>();

List extends NaturalNumber> ln = le;

ln.add(new NaturalNumber(35)); // compile-time error //编译时错误

因为 List 是 List extends NaturalNumber> ,您可以赋值 le 给 ln 。但是你不能使用 ln 将自然数添加到偶数列表中。列表中的以下操作是可能的:

您可以添加null。

你可以调用清除。

您可以获取迭代器并调用remove。

您可以捕获通配符并写入从列表中读取的元素。

你可以看到 List extends NaturalNumber> 在严格意义上不是只读的,但您可能会这样想,因为您无法存储新元素或更改列表中的现有元素。

   static class Fruit{}
    static class Apple extends Fruit{}
    static class BigApple extends Apple {}


    public static void process(List<? extends Apple> list) {

    }

    public static void main(String[] args) throws Exception {
        // 下届通配符用于读取
        process(new ArrayList<Fruit>()); // 编译错
        process(new ArrayList<Apple>());
        process(new ArrayList<BigApple>());

        // 下届通配符用于读取
        List<? extends Fruit> fruitList = new ArrayList<>();
        List<? extends Apple> applelist = new ArrayList<>();
        fruitList=applelist; // 读取
        applelist=fruitList; // 读取 - 编译错
        applelist.add(new Fruit());//编译错
        applelist.add(new Apple());//编译错

        // 上界通配符用于插入
        List<? super Apple> apples = new ArrayList<>();
        List<? super Fruit> fruits = new ArrayList<>();
        fruits=apples;//编译错
        applelist=fruits;//编译错
        apples.add(new Fruit());// 编译错
        apples.add(new Apple());
        apples.add(new BigApple());
    }

泛型通配符<? extends T>来接收返回的数据,此写法的泛型集合不能使用add方法, 而<? super T>不能使用get方法,作为接口调用赋值时易出错。

1.?频繁往外读取内容的,适合用<? extends T>。

2.?经常往里插入的,适合用<? super T>。

<? extends T> = <subClass extends T> = T以及T的子类

<? super T> = <superClass super T> = T以及T的父类

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-26 11:28:38  更:2022-04-26 11:29:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:29:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码