Java泛型:灵活多变的类型参数化工具

news2024/11/20 3:27:18

在这里插入图片描述

  • 👑专栏内容:Java
  • ⛪个人主页:子夜的星的主页
  • 💕座右铭:前路未远,步履不停

目录

  • 一、泛型
    • 1、什么是泛型
    • 2、泛型的语法
  • 二、泛型类的使用
    • 1、泛型类的语法
    • 2、泛型如何编译的
      • 2.1、擦除机制
      • 2.2、为什么不能实例化泛型类型数组
    • 3、泛型方法


一、泛型

1、什么是泛型

在传统的编程方法中,类和方法通常被限定为使用特定的类型。这些类型可能是基础的数据类型(如整数、字符等),或者是由程序员自己定义的复杂类型。这种方式在处理单一类型数据时很有效,但当我们需要编写更加灵活、能够适用于多种数据类型的代码时,这种严格的类型限制就变成了一个约束。

泛型,就是为了解决这种限制而生的。简单来说,泛型可以理解为一种“类型模板”,它允许程序员编写的代码能够适应不同的数据类型,而不必为每种可能的数据类型都编写一个新版本。

泛型的厉害之处,就在于它的灵活性和重用性。你可以写一个泛型方法或类,然后在需要的时候用具体的类型去实例化它,比如整数、字符串或者是你自定义的任何类型。这样,你就可以用同一套代码处理不同类型的数据,极大地提高了代码的通用性和可维护性。

2、泛型的语法

泛型的基本语法主要包括以下几个方面:

  1. 泛型类和接口

    • 在类或接口后面加上<T>来声明一个泛型类或接口。
    • T是类型参数,代表一种未指定的类型。在实例化类或接口时,你可以用具体的类型替换它。
    • 示例:
      public class Box<T> {
          private T t;
      
          public void set(T t) {
              this.t = t;
          }
      
          public T get() {
              return t;
          }
      }
      

    这个例子中,Box类可以用任何类型的对象来实例化,例如Box<Integer>Box<String>

  2. 泛型方法

    • 泛型方法可以定义在普通类中,也可以定义在泛型类中。
    • 在方法返回类型之前使用<T>来声明一个泛型方法。
    • 示例:
      public <T> T genericMethod(T t) {
          return t;
      }
      

    这个方法可以接受任何类型的参数,并返回相同类型的对象。

  3. 类型通配符

    • 使用?表示未知类型,通常用在参数、字段、局部变量上,以及泛型方法的返回类型上。
    • 示例:
      public void processElements(List<?> elements) {
          for (Object e : elements) {
              // 处理e
          }
      }
      

    List<?>可以接受任何类型的List

  4. 限定的类型参数

    • 你可以限制类型参数可以接受的类型范围。
    • 使用extends关键字来限定类型参数的上界(即它必须是特定类或接口的子类型)。
    • 示例:
      public <T extends Number> double sum(List<T> numbers) {
          double sum = 0.0;
          for (Number n : numbers) {
              sum += n.doubleValue();
          }
          return sum;
      }
      

这个方法只接受Number类型或其子类的List

泛型存在的意义:

  • 在编译的时候,帮我们进行类型的检查。
  • 在编译的时候,帮我们进行类型的转换。

二、泛型类的使用

1、泛型类的语法

泛型类<类型实参> 变量名; // 定义一个泛型类引用

new 泛型类<类型实参>(构造方法实参); // 实例化一个泛型类对象
MyArray<Integer> list = new MyArray<Integer>();

注意:泛型只能接受类,所有的基本数据类型必须使用包装类!

2、泛型如何编译的

2.1、擦除机制

在这里插入图片描述

在编译时,Java编译器将所有的泛型类型参数替换掉,这个过程就是类型擦除。

  • 泛型类型参数被替换为它们的边界或者Object
  • 如果类型参数是有界的(<T extends Number>),编译器将类型参数替换为它的第一个边界。
  • 如果类型参数是无界的(<T>),编译器将类型参数替换为Object

Java的泛型机制是在编译级别实现的,编译器生成的字节码在运行期间并不包含泛型的类型信息

2.2、为什么不能实例化泛型类型数组

class MyArray<T> {
    public T[] array = (T[])new Object[10];
    public T getPos(int pos) {
        return this.array[pos];
    }
    public void setVal(int pos,T val) {
        this.array[pos] = val;
    }
    public T[] getArray() {
        return array;
    }
}

public class demo1 {
    public static void main(String[] args) {
        MyArray<Integer> myArray1 = new MyArray<>();
        Integer[] strings = myArray1.getArray();
    }
}

在这里插入图片描述
由于类型擦除的原因,不能直接创建一个泛型数组。类型擦除会将泛型类型参数T替换为Object,这导致了类型不匹配,从而在运行时抛出ClassCastException

3、泛型方法

语法:方法限定符 <类型形参列表> 返回值类型 方法名称(形参列表) { ... }

例子:写一个泛型方法,用于交换数组中两个元素的位置:

public class GenericMethodTest {
    // 泛型方法 printArray
    public static < E > void printArray( E[] inputArray ) {
        for(E element : inputArray) {
            System.out.printf("%s ", element);
        }
        System.out.println();
    }

    public static void main(String args[]) {
        // 创建不同类型数组: Integer, Double 和 Character
        Integer[] intArray = { 1, 2, 3, 4, 5 };
        Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
        Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };

        System.out.println("整型数组元素为:");
        printArray(intArray);   // 传递一个整型数组

        System.out.println("\n双精度型数组元素为:");
        printArray(doubleArray);   // 传递一个双精度型数组

        System.out.println("\n字符型数组元素为:");
        printArray(charArray);   // 传递一个字符型数组
    }
}

  • 泛型方法可以声明在普通类或泛型类中。
  • 泛型方法的声明包括一个类型参数部分,跟在方法的修饰符和返回类型之前。
  • 类型参数部分是一个尖括号括起来的类型参数列表,如<T>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1371100.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

coredump+gdb调试

1、什么是coredump Coredump&#xff08;核心转储&#xff09;是操作系统在程序异常终止&#xff08;例如由于段错误或其他严重错误&#xff09;时创建的一种文件。这个文件包含了程序崩溃时刻进程的内存镜像&#xff0c;通常还包括程序计数器、寄存器内容和堆栈内存等信息&am…

Goby高级食用指南

Goby高级食用指南 1.Goby POC2.自定义字典3.Goby插件生态 - 一些好用的插件分享FOFASubDomainsBruteExportCsvAWVSRedis-cliGoby4waf初级篇参考 - Goby基本使用 1.Goby POC Goby的漏洞模块包含官方自定义的一些初始POC: 红队版的POC会实时更新,普通版则不会 Goby的POC编写…

MySQL8.0 升级

将 MySQL8.0.30 升级到 MySQL8.0.32 备份旧数据 rootLAPTOP-FPIQJ438:/data/backup# xtrabackup --backup --userroot --password123456 --socket/tmp/mysql.sock --target-dir/data/backup/ 2024-01-08T16:46:38.98768708:00 0 [Note] [MY-011825] [Xtrabackup] recognized s…

江山易改本性难移之ZYNQ SDK QSPI固化bug及其解决方法

之前在Vivado2018.3通过QSPI方式固化程序时出现问题&#xff0c;显示flash擦除成功&#xff0c;但最后总是不能写入到flash中。 查资料发现从VIVADO 2017.3版本开始&#xff0c;Xilinx官方为了使Zynq-7000和Zynq UltraScale 实现流程相同&#xff0c;在QSPI FLASH使用上做了变化…

VSCode C/C++(gdb)调试指南

1、安装插件 2、F5开启调试 左侧侧边栏->确保打开回调栈 右键函数栈->查看反汇编 3、打印寄存器、函数反汇编等 命令&#xff1a; 查看main反汇编 -exec disassemble /m main 查看寄存器 -exec info r 打印某个变量 -exec print s 或者 --s 打印寄存器&#xff0c;如p…

Git删除远程仓库某次提交记录后的所有提交

1、鼠标右键->git bash here&#xff0c;然后cd切换到代码目录&#xff1b; 2、git log查看提交记录&#xff0c;获取commit id 3、git reset commit id&#xff08;commit id指要保留的最新的提交记录id&#xff09; 4、git push --force&#xff0c;强制push 如果出现…

来自一个系统的自白

天空一声巨响&#xff0c;小炫我闪亮登场&#xff01;初次见面&#xff0c;给大家简单介绍下自己&#xff1a;我是炫我渲染私有云系统&#xff0c;是最新一代的智能渲染集群系统。可以进行私有化部署&#xff0c;在3dsmax、maya等软件中一键完成提交、上传、渲染、下载的任务&a…

强化学习第1天:马尔可夫过程

☁️主页 Nowl &#x1f525;专栏 《强化学习》 &#x1f4d1;君子坐而论道&#xff0c;少年起而行之 ​​ 一、介绍 什么是马尔可夫过程&#xff1f;马尔可夫过程是马尔可夫决策过程的基础&#xff0c;而马尔可夫决策过程便是大部分强化学习任务的抽象过程&#xff0c;本文…

人机交互不是人机融合智能

一、人机交互和人机融合智能是两个不同的概念 人机交互是指人类与计算机之间的信息交流和操作方式&#xff0c;包括输入和输出界面、交互技术、用户体验等方面。人机交互的目标是提供用户友好的界面和自然的交互方式&#xff0c;使人类能够与计算机更加高效地进行沟通和协作。 …

BOM简介

1.1 常用的键盘事件 1.1.1 键盘事件 键盘事件触发条件onkeydown按键被按下时触发onkeypress按键被按下时触发onkeyup按键被松开时触发 注意&#xff1a;addEventListener事件不需要加on <script>//1. keydown 按键按下的时候触发,按任意键都触发&#xff0c;也可以识…

PhpPythonC++圆类的实现(OOP)

哎......被投诉了 &#x1f62d;&#x1f62d;&#x1f62d;&#x1f62d;&#x1f62d; 其实也不是小编不更&#xff0c;这不是期末了吗&#xff08;zhaojiekou~~&#xff09;&#xff0c;而且最近学的信息收集和ctf感觉好像没找到啥能更的&#xff08;不过最经还是在考虑更一…

Java中并发下的ThreadlocalRandom

1. 背景 在看同事写的代码的时候发现代码里有很多像&#xff1a; 如果我们想要生成一个随机数&#xff0c;通常会使用Random类。但是在并发情况下Random生成随机数的性能并不是很理想&#xff0c;今天给大家介绍一下JUC包中的用于生成随机数的类–ThreadLocalRandom.&#x…

领英Linkedin自动跳转中国站点的解决方案

linkedin放弃中国市场后&#xff0c;在国内打开linkedin.com&#xff0c;会自动跳转到 linkedin.cn&#xff0c;无法与国际友人在同一个平台上联系。 按照搜到的方法尝试解决&#xff0c;包括修改浏览器默认语言、清除浏览数据、使用软路由上的插件给 linkedin.com设置从国外线…

华为 1+X《网络系统建设与运维(高级)》认证模拟实验上机试题

华为 1X《网络系统建设与运维&#xff08;高级&#xff09;》认证模拟实验上机试题 一、考试背景二、考试说明2.1考试分数说明2.2考试要求2.3考试环境介绍2.4启动考试环境2.5保存答案(非常重要) 三、考试正文3.1注意事项3.2校区内&#xff08;LAN&#xff09;3.2.1任务 1&#…

深入浅出Go语言:匿名函数的原理和实践案例

深入浅出Go语言&#xff1a;匿名函数的原理和实践案例 引言匿名函数的基础实际应用案例一实际应用案例二性能考虑最佳实践与常见错误结语 引言 在Go语言的世界里&#xff0c;有一个功能强大且灵活的编程元素值得每位开发者深入了解——匿名函数。作为Go语言核心特性之一&#…

前端-基础 表格标签 - 基本使用及表头单元格 详解

基本使用 &#xff1a; 主要作用 &#xff1a; 即 主要 用于显示&#xff0c;展示数据&#xff0c;因为它可以让数据显示的非常的规整&#xff0c;可读性非常好。 特别是后台展示数据的时候&#xff0c;能够熟练运用表格就显得很重要。 一个清爽简约的表格能够把繁杂 的…

C2-4.3.1 多个决策树——随机森林

C2-4.3.1 多个决策树——随机森林 参考链接 1、为什么要使用多个决策树——随机森林&#xff1f; 决策树的缺点&#xff1a; A small change in the data can cause a large change in the structure of the decision tree causing instability 即&#xff1a;对数据集 中…

数据库:如何取消mysql的密码

因为调试MySQL数据接口&#xff0c;总是需要输入密码很烦&#xff0c;所以决定取消mysql的root密码&#xff0c; 网上推荐的有两种方法&#xff1a; 1、mysql命令 SET PASSWORD FOR rootlocalhostPASSWORD(); 2、运行 mysqladmin 命令 mysqladmin -u root -p password …

【源码阅读】交易池txs_pool

重要接口&#xff1a; ITxsPool的实现&#xff1a; type TxsPool struct {config TxsPoolConfigchainconfig *params.ChainConfigbc common.IBlockChaincurrentState *state.IntraBlockStatependingNonces *txNoncercurrentMaxGas uint64ctx context.Context //cance…

密码学(一)

文章目录 前言一、Cryptographic Primitives二、Cryptographic Keys2.1 Symmetric key cryptography2.2 asymmetric key cryptography 三、Confidentiality3.1 Symmetric key encryption algorithms3.2 asymmetric key block ciphers3.3 其他 四、Integrity4.1 secure hashing …