码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 浅学JAVA泛型一:泛型的基础知识


    前言:

    阅读本章内容,你可以学到如下知识:

    1. 泛型是什么
    2. 为什么要使用泛型
    3. 泛型中的E,K,N,T分别代表什么?
    4. 泛型的使用

    一丶泛型是什么?

    泛型就是具体的类型参数化,在具体传入或者调用时才去传入具体的类型。(指定容器要持有什么类型的对象,由编译器保证类型的正确性)

    二丶为什么要使用泛型

    先看个例子,以我们最常用的list集合举例,如果我们没有泛型,集合里面放的都是Object对象


     

    1. public static void main(String[] args) {
    2. List listObject = new ArrayList<>();
    3. listObject.add(1);
    4. listObject.add(new Album());
    5. System.out.println(listObject);
    6. for (Object object : listObject) {
    7. String str = (String) object;
    8. System.out.println(str);
    9. }
    10. List listStr = new ArrayList<>();
    11. listStr.add("str1");
    12. listStr.add("str12");
    13. for (String s : listStr) {
    14. System.out.println(s);
    15. }
    16. }
    17. 从上面代码我们可以发现两个问题

      1. 我们listObject其实放的是Integer和Number类型,我们在编译时可以随意强制转换然后进行方法调用,但是我们将Integer和Number类型都转换为String其实在运行期是会报错的,我们这里的错误就推迟到运行期才暴露出来,而使用泛型我们在编译器就可以提前做类型检查,这样错误就在编译期暴露出来了
      2. 我们看到第二个listStr集合,因为我们指定了泛型是String,所以当我们使用list中的元素就不用做强制转换。

      我们再看一段代码


       

      1. public class Main {
      2. @Test
      3. public void test() {
      4. String messageContent = "[message]:泛型真好用";
      5. String commentContent = "[comment]:泛型真好用";
      6. Message message = new Message();
      7. Comment comment = new Comment();
      8. execute(messageContent, message::setContent);
      9. execute(commentContent, comment::setContent);
      10. System.out.println(message.getContent()); // [message]:泛型真好用
      11. System.out.println(comment.getContent()); // [comment]:泛型真好用
      12. }
      13. private void execute(T t, Consumer consumer) {
      14. consumer.accept(t);
      15. }
      16. }
      17. class Message {
      18. private String content;
      19. public String getContent() {
      20. return content;
      21. }
      22. public void setContent(String content) {
      23. this.content = content;
      24. }
      25. }
      26. class Comment {
      27. private String content;
      28. public String getContent() {
      29. return content;
      30. }
      31. public void setContent(String content) {
      32. this.content = content;
      33. }
      34. }
      1. 我们在上面那个例子中可以发现,我们定义了两个类,Message和Comment,然后我们定义了一个execute方法,传入了一个泛型和一个消费型函数,我们在里面执行accept方法,这样我们这个方法相当于是一个通用的算法,我们可以传入任意对象然后实现不同的consumer函数就行

      所以可以总结一下我们为什么要使用泛型

      1. 在编译时会有更强的类型检查,使我们在编译期就可以发现一些类型转换的问题(修复编译期错误比修复运行期错误更容易,因为运行期的错误很难找到)

      2. 我们使用泛型,在重写时定义好了泛型类型,就不需要在代码中进行强制转换了

      3. 我们可以通过泛型实现更加通用的算法

      三丶泛型中的E,K,N,T分别代表什么?

      • E:元素(在java集合框架中广泛使用)
      • K:键(Map)
      • N:数字
      • T:类型
      • V:值 (作为返回值或者映射值)
      • S,U,V等:第2,第3,第4类型

      它们其实是可以完全互换的,只是我们这样定义是一个约定

      四丶泛型的使用

      老规矩,我们还是先看代码

      1. class Node {
      2. private K k;
      3. private V v;
      4. public Node(K k, V v) {
      5. this.k = k;
      6. this.v = v;
      7. }
      8. public K getK() {
      9. return k;
      10. }
      11. public void setK(K k) {
      12. this.k = k;
      13. }
      14. public V getV() {
      15. return v;
      16. }
      17. public void setV(V v) {
      18. this.v = v;
      19. }
      20. public extends BaseInteface> void sengMessage(T t){
      21. System.out.println(t.num);
      22. }
      23. }
      • 类或者接口上面使用泛型我们需要在类名后面写一个<>,然后再写上我们的泛型(定义几个泛型,<>放几个泛型),我们在方法上面就可以使用这些泛型了

      • 我们在方法上使用泛型有两种方式

        • 使用我们类已经定义好了的泛型直接使用即可
        • 使用我们没有在类中定义的泛型我们在方法名前使用尖括号定义泛型即可

      我们接下来再看看我们经常说的上界通配符和下界通配符

      1. public class Wildcar extends Number, V extends BaseIntefaceImpl>{
      2. private T t;
      3. private V v;
      4. public Wildcar(T t, V v) {
      5. this.t = t;
      6. this.v = v;
      7. }
      8. public void show(Listsuper Number> lists){
      9. }
      10. public static void main(String[] args) {
      11. Wildcar intefaceWildcar = new Wildcar<>(1, new BaseInfoParent());
      12. System.out.println(intefaceWildcar.t.intValue());
      13. System.out.println(intefaceWildcar.v);
      14. }
      15. }

      T extends Number:这里是使用的上界通配符,我们在后面代码中所定义的T只能是extend的子类

      List lists:这里使用的是下界通配符,表示填充为任意Number的父类

    18. 相关阅读:
      gRPC协议详解
      某米ax3000路由器组网解析
      详解设计模式:状态模式
      使用免费开源软件 Blender 编辑视频
      Windows下的RabbitMQ安装教程(遇到很多无语的问题,已解决)
      vscode 创建 运行c++ 项目
      经典算法之希尔排序
      M2DGR 多源多场景 地面机器人SLAM数据集
      股票程序交易接口的测试流程
      js获取对象值得方式(在不确定对象参数的情况下获取值)
    19. 原文地址:https://blog.csdn.net/m0_73088370/article/details/126365821
      • 最新文章
      • 攻防演习之三天拿下官网站群
        数据安全治理学习——前期安全规划和安全管理体系建设
        企业安全 | 企业内一次钓鱼演练准备过程
        内网渗透测试 | Kerberos协议及其部分攻击手法
        0day的产生 | 不懂代码的"代码审计"
        安装scrcpy-client模块av模块异常,环境问题解决方案
        leetcode hot100【LeetCode 279. 完全平方数】java实现
        OpenWrt下安装Mosquitto
        AnatoMask论文汇总
        【AI日记】24.11.01 LangChain、openai api和github copilot
      • 热门文章
      • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
        奉劝各位学弟学妹们,该打造你的技术影响力了!
        五年了,我在 CSDN 的两个一百万。
        Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
        面试官都震惊,你这网络基础可以啊!
        你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
        心情不好的时候,用 Python 画棵樱花树送给自己吧
        通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
        13 万字 C 语言从入门到精通保姆级教程2021 年版
        10行代码集2000张美女图,Python爬虫120例,再上征途
      Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
      正则表达式工具 cron表达式工具 密码生成工具

      京公网安备 11010502049817号