码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • Java泛型中K、T、V、E、?等的含义


    1.概述

      在定义泛型类、接口和方法时,都会定义一个参数类型,我们用过、、等,那么这些字母有什么区别和不同呢?
      定义Java的泛型时,通常使用的一些类型参数的字母或者符号有:E、T、K、V、N、?Object等。
      首先,E、T、K、V、N等这些字母之间没什么区别,使用T的地方完全可以换成U、S、Z等任意字母。当然,一般我们会使用一些常用的字母,这些字符一般是一些类型的缩写。
      例如:

    • E : Element的缩写,一般在集合中使用,表示集合中的元素类型。
    • T : Type的缩写,一般表示Java类。
    • K : Key的缩写,一般用来表示“键”,如Map种的key。
    • V : Value的缩写,一般用来表示“值”与K是一对。
    • N : Number的缩写,通常用来表示数值类型。

      以上这些类型其实都是确定的类型,如List表示List中的类型只能是T。
      除此之外,还有不确定的类型,那就是?,表示不确定的Java类型,也经常出现在集合类中。
      需要注意的是,在Java集合框架中,对于参数值是位置类型的容器类,只能读取其中的元素不能向其中添加元素。因为其类型是未知的,所以编译器无法识别添加元素的类型和容器的类型是否兼容,唯一的例外是null

    List list = new ArrayList<>();
    list.add(null); //编译通过
    list.add(“Hollis”) // 编译失败

      List是一个未知类型的List,不能向List中添加元素,但可以把List,List赋值给List。
    在这里插入图片描述
    在这里插入图片描述

      很多人认为List和List是一样的,其实这是不对的,表示任意类型,表示未知类型,可以向List中添加元素,但是不能把List赋值给List。

    2.泛型中的限定通配符合非限定通配符

      假设你需要一个List来存放Fruits,那么你会定义List fruits,你能直接把List赋值给fruits吗(Apple 继承自 Fruit)?
    不能
    在这里插入图片描述
      以上代码编译失败的原因是List中允许添加任何水果,而List中只允许添加apple,这意味着两种类型不兼容。
    如果我们只关心List包含某种类型的水果这一事实,那么我们就可以使用类型通配符来定义它

    public class Demo {
        public static void main(String[] args) {
            List<Apple> apples = new ArrayList<Apple>();
            List<? extends Fruits> fruits = apples;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

      使用List定义的List是可以接收List的,通过这种形式表名这是一个Fruit或者它的子类List么这意味着列表中的每个元素都是某种水果。

      但是我们不能直接向List fruits中添加元素:
    在这里插入图片描述
    因为上面代码定义的List可能是List或Fruit的其他子类List。

    3. 限定通配符与非限定通配符

    像这种形式,我们称之为通配符。Java泛型中有两种限定通配符。
    一种是,保证泛型类型必须是T的子类型来设定泛型类型的上边界,即泛型类型必须为T类型或者T的子类。

    public class Demo {
        public static void main(String[] args) {
            List<Apple> apples = new ArrayList<Apple>();
            List<? extends Fruits> fruits = apples;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    另一种是保证泛型类型必须是T的父类来设定类型的下边界,即类型必须是T类型或者T的父类。

    public class Demo {
        public static void main(String[] args) {
            List<Fruits> fruits = new ArrayList<>();
            List<? super Apple> apples = fruits;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    是非限定通配符,表示可以用任意泛型来替代它,即可以把任意类型的List赋值给 List

    public class Demo {
        public static void main(String[] args) {
            List<Apple> apples = new ArrayList<Apple>();
            List<Anything> anythings = new ArrayList<>();
            List<?> fruits = apples;
            List<?> fruits = anythings;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4.泛型的PECS原则

      前面介绍了两个限定通配符和,这两个通配符在什么时候使用,使用时又该如何选择呢?
      这就不得不提到一个原则–PECS原则,即Producer Extens Consumer Super,这是在集合中使用限定通配符的一个原则。
      如果只是从一个泛型集合中提取元素,那么它是一个生成器(Producer),应该使用Extends:

    List<? extends Fruits> fruits = new ArrayList<>();
    fruits.add(new Apple()) //编译失败
    
    • 1
    • 2

    当我们尝试向一个生成器中添加元素时,会编译失败。这是因为编译器只知道这个List中的元素是Fruit及其子类,但具体是那种类型编译器是不知道的。
      如果是向集合中添加元素,那么它是一个消费者(Consumer),应该使用Super:
    在这里插入图片描述
      当我们尝试从消费者中提取元素时,也会编译失败。这是因为编译器只知道这个List中的元素是Apple及其父类,具体是那种类型的编译器是不知道的。
      简单地说,在集合中,频繁地往外读取内容的场景,适用于;经常向集合中插入的场景适合于
      另外,如果想在同一个集合中同时使用这两种方法,则不该使用Extends或Super。

  • 相关阅读:
    基于稳态视觉诱发电位和注意力脑电的混合脑机接口系统
    Google VS Facebook,哪个能带来更好的效果?
    CSS三种样式表、样式表优先级、CSS选择器
    一文搞懂堆外内存(模拟内存泄漏)
    供应商管理
    计算机丢失mfc140.dll是什么意思?附送修复教程
    智能决策:数字孪生的商业洞察
    YOLOv5-6.1源码详解之损失函数loss.py
    吹缆机的原理与应用——TFN 吹缆机 T700C系列
    你不可不知的八大全新顶级开源项目
  • 原文地址:https://blog.csdn.net/Blue_Pepsi_Cola/article/details/127863669
    • 最新文章
    • 沪漂五周年了:我越来越迷茫了
      Agentic Skill Routing 实战:别再把所有 Skill 塞进 AI Agent 上下文
      MySQL-Seconds_behind_master的精度误差
      [MAF预定义ChatClient中间件-03]CachingChatClient——利用缓存省钱省时间
      AI的至暗历史:从万众期待到被政府撤资,AI的两次死亡徘徊
      Agent OS :五种驯服不确定性的范式
      PortSwigger SQL注入LAB11
      数据库即时编译JIT
      [Begin]AI Learn Data Day 0
      深度学习进阶(二十七)现代 LLM 的核心架构设计其二:SwiGLU
    • 热门文章
    • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
      奉劝各位学弟学妹们,该打造你的技术影响力了!
      五年了,我在 CSDN 的两个一百万。
      Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
      面试官都震惊,你这网络基础可以啊!
      你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
      心情不好的时候,用 Python 画棵樱花树送给自己吧
      通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
      13 万字 C 语言从入门到精通保姆级教程2021 年版
      10行代码集2000张美女图,Python爬虫120例,再上征途
    小工具 小游戏
    Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

    京公网安备 11010502049817号