Java 包装类初识泛型

 登神长阶 第六阶  包装类&初识泛型


目录

😀一.包装类

😄1.基本数据类型以及其对应的包装类

😂2.装箱和拆箱

😇2.1.装箱(Boxing)

😉2.2.拆箱(Unboxing)

🫠2.3.注意事项

🥰二.泛型

😍1. 泛型类和泛型接口

🤩2.泛型类的具体使用

😜三.泛型方法

🤗1. 声明泛型方法

🫡2. 调用泛型方法

😛3. 类型推断

🤨4. 泛型方法与泛型类的关系

😷5. 泛型方法的优势

🤤四.泛型类的具体编译

🥴1. 类型擦除(Type Erasure)

😵‍💫2. 桥接方法(Bridge Method)

🤠3. 示例

🧐五.泛型的上界

😎1. 声明上界

🥹2.使用上界的好处

😣3. 上界通配符

😤4.注意事项 

🤓六.总结与反思


😀一.包装类

定义

        在Java中,由于基本类型不是继承自Object,为了在泛型代码中可以支持基本类型,Java给每个基本类型都对应了一个包装类型。包装类用于将基本数据类型转换为对象。它们允许在对象上执行额外的操作,例如将基本数据类型作为参数传递给方法,或者在集合类中存储基本数据类型。 

😄1.基本数据类型以及其对应的包装类

基本数据类型包装类

byte

Byte
shortShort
intInterger
longLong
floatFloat
doubleDouble
char

Character

booleanBoolean
除了 Integer Character , 其余基本类型的包装类都是首字母大写

😂2.装箱和拆箱

在Java中,装箱(boxing)和拆箱(unboxing)是指将基本数据类型转换为对应的包装类对象,以及将包装类对象转换为基本数据类型的过程。在使用过程中,装箱和拆箱带来不少的代码量,所以为了减少开发者的负担,java 提供了自动机制

😇2.1.装箱(Boxing)

装箱是指将基本数据类型转换为对应的包装类对象。在Java中,这个过程是自动进行的,称为自动装箱(autoboxing)。例如,将int类型的值装箱为Integer对象:

int num = 10;
Integer wrappedNum = num; // 自动装箱

😉2.2.拆箱(Unboxing)

拆箱是指将包装类对象转换为对应的基本数据类型。同样,这个过程也是自动进行的,称为自动拆箱(unboxing)。例如,将Integer对象转换为int类型:

Integer wrappedNum = 10;
int num = wrappedNum; // 自动拆箱

🫠2.3.注意事项

  • 自动装箱和拆箱可以使基本数据类型与其对应的包装类对象之间转换更加方便。
  • 自动装箱和拆箱发生在编译时,编译器会自动插入相应的代码。
  • 在使用自动装箱和拆箱时,需要注意空指针异常(NullPointerException),因为如果包装类对象为null,拆箱操作可能会导致异常。

总的来说,装箱和拆箱提供了方便的方式来在基本数据类型和包装类对象之间进行转换,同时避免了手动进行类型转换的繁琐工作。

🥰二.泛型

        在Java中,泛型(Generics)是一种强大的特性,用于在编译时检查和确保程序的类型安全性。泛型允许类、接口和方法在定义时使用一个或多个类型参数,以便在实际使用时可以指定具体的类型。

💡 一般的类和方法,只能使用具体的类型: 要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大。----- 来源《 Java 编程思想》对泛型的介绍。
        泛型是在JDK1.5 引入的新的语法,通俗讲,泛型: 就是适用于许多许多类型 。从代码上讲,就是对类型实现了参数化。

😍1. 泛型类和泛型接口

  • 可以通过在类名后面使用尖括号<>来声明泛型类。
  • 泛型类可以包含一个或多个类型参数,用于指定具体类型。
  • 泛型接口的定义与泛型类类似,可以在接口中定义泛型类型参数。

 语法

public class Box<T> {private T value;public Box(T value) {this.value = value;}public T getValue() {return value;}
}
class 泛型类名称<类型形参列表> {// 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> {
}
class 泛型类名称<类型形参列表> extends 继承类/* 这里可以使用类型参数 */ {// 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> extends ParentClass<T1> {// 可以只使用部分类型参数
}

 举例

class MyArray<T> {public T[] array = (T[])new Object[10];//1public T getPos(int pos) {return this.array[pos];}public void setVal(int pos,T val) {this.array[pos] = val;}
}public class TestDemo {public static void main(String[] args) {MyArray<Integer> myArray = new MyArray<>();//2myArray.setVal(0,10);myArray.setVal(1,12);int ret = myArray.getPos(1);//3System.out.println(ret);myArray.setVal(2,"bit");//4}
}
上述代码解释:
  1. 类名后的 <T> 代表占位符,表示当前类是一个泛型类
【规范】类型形参一般使用一个大写字母表示,常用的名称有:
  • E 表示 Element
  • K 表示 Key
  • V 表示 Value
  • N 表示 Number
  • T 表示 Type
  • S, U, V 等等 - 第二、第三、第四个类型
  2. 注释1 处,不能 new泛型类型的数组
这是因为Java泛型是通过类型擦除实现的,在运行时并不知道泛型的具体类型,而数组在创建时需要明确知道元素的类型。因此,创建泛型数组会导致编译器产生警告或错误。
  3. 注释 2 处,类型后加入 <Integer> 指定当前类型
  4. 注释 3处,不需要进行强制类型转换
  5. 注释 4 处,代码编译报错,此时因为在注释 2 处指定类当前的类型,此时在注释 4处,编译器会在存放元素的时候帮助我们进行类型检查

🤩2.泛型类的具体使用

语法

泛型类<类型实参> 变量名; // 定义一个泛型类引用
new 泛型类<类型实参>(构造方法实参); // 实例化一个泛型类对象
示例
MyArray<Integer> list = new MyArray<Integer>();

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

类型推导 (Type Inference)
当编译器可以根据上下文推导出类型实参时,可以省略类型实参的填写
MyArray < Integer > list = new MyArray <> (); // 可以推导出实例化需要的类型实参为 Integer

😜三.泛型方法

泛型方法是在方法声明时带有类型参数的方法。它们可以独立于所属类进行参数化,并且可以在调用时指定具体类型。以下是关于泛型方法的详细描述:

🤗1. 声明泛型方法

  • 在方法声明时,在返回类型之前使用尖括号<>来声明类型参数。

泛型方法可以有一个或多个类型参数,这些参数在方法中可以被用作参数类型、返回类型或局部变量类型。

public <T> void printArray(T[] array) {for (T element : array) {System.out.println(element);}
}

🫡2. 调用泛型方法

  • 在调用泛型方法时,可以在方法名之前使用尖括号<>来指定具体的类型参数。
  • 编译器会根据指定的类型参数来进行类型检查和类型推断。
Integer[] intArray = {1, 2, 3, 4, 5};
String[] strArray = {"Hello", "World"};printArray(intArray); // 调用泛型方法并传入整型数组
printArray(strArray); // 调用泛型方法并传入字符串数组

😛3. 类型推断

  • 在调用泛型方法时,如果可以通过上下文推断出类型参数,可以省略类型参数的显式指定。
  • 编译器会根据方法参数的类型来推断类型参数。
Integer[] intArray = {1, 2, 3, 4, 5};
printArray(intArray); // 编译器会推断类型参数为Integer

🤨4. 泛型方法与泛型类的关系

  • 泛型方法可以独立于所属类进行参数化,即使所属类不是泛型类也可以定义泛型方法。
  • 泛型方法可以在普通类、泛型类、接口中声明和调用。
public class Utils {public static <T> T getLastElement(T[] array) {return array[array.length - 1];}
}Integer[] intArray = {1, 2, 3, 4, 5};
Integer lastElement = Utils.getLastElement(intArray);

😷5. 泛型方法的优势

  • 提高代码的重用性和灵活性。
  • 可以在方法级别实现类型安全。

总的来说,泛型方法是Java中一种强大的特性,它允许在方法级别使用泛型,提高了代码的可复用性和类型安全性。通过类型推断简化调用。

🤤四.泛型类的具体编译

泛型类在Java中的编译过程涉及到类型擦除和桥接方法等概念。

以下是泛型类的具体编译过程:

🥴1. 类型擦除(Type Erasure)

  • 在编译阶段,泛型信息会被擦除,即将泛型类中的类型参数擦除为它们的边界或Object类型。
  • 泛型类中的类型参数会被替换为对应的边界类型或Object类型。
  • 泛型类的实例化和操作都是基于擦除后的类型进行的。

😵‍💫2. 桥接方法(Bridge Method)

  • 当泛型类中包含泛型方法时,在编译生成字节码时,编译器会自动生成桥接方法来保证泛型方法的类型安全性。
  • 桥接方法是编译器为了兼容Java泛型擦除机制而生成的方法,用于确保泛型类或泛型接口的方法能够正确地调用。
  • 桥接方法会根据擦除后的方法签名生成一个桥接方法,以便正确调用泛型方法。

🤠3. 示例

假设有以下泛型类定义:

public class Box<T> {private T value;public Box(T value) {this.value = value;}public T getValue() {return value;}
}

在编译后,上述代码会被转换为类似如下的形式:

public class Box {private Object value;public Box(Object value) {this.value = value;}public Object getValue() { // 编译后的桥接方法return value;}
}

这样,在泛型类的编译过程中,会进行类型擦除和桥接方法生成等操作,以确保在运行时可以正确处理泛型类的实例化和操作。

有关泛型擦除机制的文章截介绍: Java泛型擦除机制之答疑解惑 - 知乎 (zhihu.com)

🧐五.泛型的上界

在Java的泛型中,上界(Upper Bound)是指限定泛型类型参数必须是某个类或其子类。通过使用上界,可以在泛型中指定类型参数的范围,从而提高类型安全性和灵活性。

😎1. 声明上界

  • 在使用泛型时,可以使用extends关键字声明上界。
  • 语法格式为<T extends ClassName>,表示泛型类型参数T必须是ClassName类或其子类。
    public class Box<T extends Number> {private T value;public Box(T value) {this.value = value;}public T getValue() {return value;}
    }
    

🥹2.使用上界的好处

  • 类型限制:通过上界,可以限制泛型类型参数的范围,只允许特定类型或其子类作为参数。
  • 类型安全:使用上界可以避免在泛型中处理不符合要求的类型,提高类型安全性。
  • 方法调用:可以在泛型类或方法中调用上界类的方法,保证对应的操作是支持的。

😣3. 上界通配符

  • 上界通配符也可以在方法参数中使用,用于接受指定上界类型的对象。
public void processList(List<? extends Number> list) {// 对于Number及其子类的列表进行处理
}

😤4.注意事项 

  • 上界是单继承的,只能指定一个类作为上界。
  • 如果需要多个上界,请考虑使用接口作为上界。
  • 超类或接口可以放在泛型类型参数的位置,以限定类型参数的范围。

通过使用上界,可以有效地约束泛型类型参数的范围,提高代码的可读性、可维护性,并确保类型安全性。通过使用上界,可以有效地约束泛型类型参数的范围,提高代码的可读性、可维护性,并确保类型安全性。

🤓六.总结与反思

💡失败固然痛苦,但更糟糕的是从未去尝试。——西奥多.罗斯福

学习Java中的泛型是一次深刻的体验。泛型不仅提升了代码的类型安全性,还增加了代码的灵活性和复用性。初次接触时,可能会感觉有些晦涩难懂,需要花费一些时间去理解其工作原理和特性。然而,通过持续的学习和实践,逐渐能够领悟到泛型所带来的价值。

泛型使得在编译时就能够检查和确保数据类型的匹配,避免了在运行时可能出现的类型转换错误,从而提高了代码的健壮性。同时,泛型也允许我们编写更加通用和抽象的代码,可以独立于具体类型来设计和实现方法或类。这种灵活性使得我们可以更轻松地编写可复用的代码,同时提高了代码的可维护性和可扩展性。

尽管初期可能会面临一些学习曲线和挑战,但是通过不断地学习和实践,逐渐能够理解泛型的工作原理,并能够熟练地运用于实际项目中。泛型所带来的类型安全性和代码重用性是非常宝贵的,它能够帮助我们编写更加清晰、健壮和可维护的代码,从而提高了开发效率和代码质量。

因此,学习泛型是Java编程中不可或缺的一步。通过持续学习和实践,我们能够更好地利用泛型这一强大工具,开发出高效、可靠的程序,迈向优秀的Java开发者之路。


🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀

以上,就是本期的全部内容啦,若有错误疏忽希望各位大佬及时指出💐

  制作不易,希望能对各位提供微小的帮助,可否留下你免费的赞呢🌸

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【项目技术介绍篇】若依项目代码文件结构介绍

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过大学刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0…

55 npm run serve 和 npm run build 的分包策略

前言 这里我们来看一下 vue 这边 打包的时候的一些 拆分包的一些策略 我们经常会使用到 npm run build 进行服务的打包 然后 打包出来的情况, 可能如下, 可以看到 chunk-vendors 是进行了包的拆分, 我们这里就是 来看一下 这里 npm run build 的时候的, 一个分包的策略 测试…

【Linux实验室】NFS、DHCP的搭建

NFS、DHCP的搭建 1、nfs服务搭建及测试什么是NFS&#xff1f;环境准备服务端机器安装nfs-utils和rpcbind包启动NFS服务创建/data/NFSdata目录&#xff0c;配置nfs文件启动服务挂载测试在服务端在共享目录下创建文件测试在客户端在共享目录下创建文件 2、dhcp服务搭建及测试什么…

如何保护IP地址不被泄露?

当互联网成为每个家庭的重要组成部分后&#xff0c;IP地址就成了你的虚拟地址。您的请求从该地址开始&#xff0c;然后 Internet 将消息发送回该地址。那么&#xff0c;您担心您的地址被泄露吗&#xff1f; 对于安全意识高或者某些业务需求的用户&#xff0c;如果您正在寻找保护…

element-ui empty 组件源码分享

今日简单分享 empty 组件的源码实现&#xff0c;主要从以下三个方面&#xff1a; 1、empty 组件页面结构 2、empty 组件属性 3、empty 组件 slot 一、empty 组件页面结构 二、empty 组件属性 2.1 image 属性&#xff0c;图片地址&#xff0c;类型 string&#xff0c;无默认…

Facebook轮播广告是什么?投放过程中有哪些需要注意的吗?

轮播广告是Facebook广告形式中的一种&#xff0c;可以把3—5个广告合并到一个可滚动的广告单元中。轮播广告会出现在新鲜事即News Feed中&#xff0c;是独立站卖家常用的一种广告形式 为什么选择轮播广告&#xff1f; 转化率更高&#xff1a;相较于单图广告&#xff0c;轮播广…

LeetCode-热题100:2. 两数相加

题目描述 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都…

Day43 动态规划 part05

Day43 动态规划 part05 1049.最后一块石头的重量II 我的思路: 提示说和划分两个和相等的子集差不多&#xff0c;猛然想到&#xff0c;这道题不就是划分子集&#xff0c;用sum - 和最大*2 代码就是划分和相同的子集的变形 解答&#xff1a; class Solution {public int last…

Cache多核之间的一致性MESI

快速链接: 【精选】ARMv8/ARMv9架构入门到精通-[目录] &#x1f448;&#x1f448;&#x1f448; 思考: 1、为什么要学习MESI协议&#xff1f; 哪里用到了&#xff1f;你确定真的用到了&#xff1f; 2、MESI只是一个协议&#xff0c;总得依赖一个硬件去执行该协议吧&#xff0c…

蓝桥杯 --- 日期问题模板

目录 1.如何判断闰年 2.如何遍历当前年份的每一天 3.如果想要输出某一年某一天到某一年某一天之间一共有多少天。 4.精确到具体周几到周几的问题分析 5.如何直接通过一层for循环枚举年月日 习题&#xff1a; 蓝桥杯竞赛特别喜欢考日期问题&#xff0c;今天给大家分享一下…

VMware虚拟机安装Linux教程

以管理员身份运行VMware 按一下win键不然显示不全 重启即可。

什么是智慧公厕?智慧旅游下的智慧公厕功能和特点

智慧旅游下的智慧公厕功能和特点&#xff1f;智慧旅游是景区、公园、游乐场、文化场馆等领域的一种信息化解决方案&#xff0c;智慧公厕是智慧旅游极为重要的一部分&#xff0c;能大大提升游客满意度。智慧公厕采用物联网、互联网、大数据、云计算等技术&#xff0c;实现旅游景…

【Spring实战项目】SpringBoot3整合WebSocket+拦截器实现登录验证!从原理到实战

&#x1f389;&#x1f389;欢迎光临&#xff0c;终于等到你啦&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;持续更新的专栏《Spring 狂野之旅&#xff1a;从入门到入魔》 &a…

picGo图床搭建gitee和smms(建议使用)

picGoGitee 这个需要下载gitee插件, 因为官方频繁的检索文件类型, 有时候也会失效 如果没有特殊要求平时存个学习的要看图中文字的重要的图片建议就是smms, 免费也够用! 图片存本地不方便, 各种APP中来回传还会失帧损失画质, 所以你值得往下看 picGosmms 建议使用这个, sm…

Linux gcc day3

find命令&#xff08;importance&#xff09;&#xff1a; 语法&#xff1a;find pathname -options find /root -name test.c which命令&#xff1a; which [指令] 只搜索指令&#xff0c;在什么位置下 为什么文件夹带有颜色呢&#xff1f; 科普补充alias命令&#xff1a; ali…

银行数字化转型导师坚鹏:银行数字化转型给分行带来的8大价值

银行数字化转型给分行带来的8大价值 银行数字化转型对不仅对总行产生了深远影响、给总行带来了新质生产力&#xff0c;对分行也会产生重要价值&#xff0c;银行数字化转型导师坚鹏从以下8个方面进行详细分析&#xff0c;相信能够给您带来重要启发&#xff0c;从而加速银行分行…

精读 Generating Mammography Reports from Multi-view Mammograms with BERT

精读&#xff08;非常推荐&#xff09; Generating Mammography Reports from Multi-view Mammograms with BERT&#xff08;上&#xff09; 这里的作者有个叫 Ilya 的吓坏我了 1. Abstract Writing mammography reports can be errorprone and time-consuming for radiolog…

clickhouse 源码编译部署

clickhouse 源码编译部署 版本 21.7.9.7 点击build project&#xff0c;编译工程&#xff0c;经过一定时间&#xff08;第一次编译可能几个小时&#xff0c;后续再编译&#xff0c;只编译有改动的文件&#xff09;生成release目录 在cmake-build-release → programs目录下…

Java集合(个人整理笔记)

目录 1. 常见的集合有哪些&#xff1f; 2. 线程安全的集合有哪些&#xff1f;线程不安全的呢&#xff1f; 3. Arraylist与 LinkedList 异同点&#xff1f; 4. ArrayList 与 Vector 区别&#xff1f; 5. Array 和 ArrayList 有什么区别&#xff1f;什么时候该应 Array而不是…

STM32L4R9 的 QuadSPI Flash 通讯速率不理想

1. 引言 客户反应 STM32L4R9 同 QSPI Flash 通讯&#xff0c;测出来的读取速率为 10MB/s&#xff0c; 和理论值相差较大。 2. 问题分析 按照客户的时钟配置和 STM32L4R9 的数据手册中的数据&#xff0c;OSPI 读数速率为 10MB/s 肯定存在问题。同时我们也可以在 AN4760 应用手…