当前位置: 首页 > news >正文

【Java入门】之为什么要有包装类 5k字详解

文章目录

  • 前言
  • 一、包装类是什么
  • 二、泛型要求
  • 三、null 值表示
    • 3.1 POJO 属性:用 null 强制提醒
    • 3.2 RPC 方法:用 null 表示调用失败
    • 3.3 Controller 方法参数:用 null 表示前端没传
  • 四、缓存机制
  • 五、类型转换
  • 六、Character 类的方法
  • 七、Integer 类的方法
  • 八、数值常量
  • 九、包装类的注意事项
  • 总结

前言

上一篇博客跟各位Java老屁股聊了lang包到底是什么(点击标题阅览文章),其中第一个提到的常用类就是包装类,那这篇博客就来探讨一下《为什么要有包装类》,它能实现什么基本数据类型所实现不了的?接下来就一一说明。

一、包装类是什么

包装类就是把基本数据类型包装成对象(即引用数据类型),使得它们也具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。

基本数据类型对应的包装类(引用数据类型)
byteByte
shortShort
intInteger
longLong
charCharacter
floatFloat
doubleDouble
booleanBoolean

继承关系:除了 Character 和 Boolean 之外,其他所有的包装类都继承自 Number 类。这种继承关系使得这些包装类能够共享一些通用的功能和特性,例如数字的比较和转换,这为在不同数值类型之间的操作提供了一致的接口。

查看继承关系的快捷键:

  • Ctrl + h 快捷键可以查看当前类的继承关系

  • 或者在源码界面右键点击“图表”,再点击“显示图”
    如果操作所示:

  • 以 Integer 为例,继承关系图如下

二、泛型要求

泛型底层用Object来存数据,取出来时再强转成对应的类型。Object是所有类的父类,它只能接收 引用数据类型(对象),不能存 基本数据类型,所以必须用包装类(Integer、Double、Character)把基本数据类型包装成对象。

//ArrayList源码,说明集合底层是个Object[]集合 transient Object[] elementData; // non-private to simplify nested class access //取出元素时,把Object强转为泛型类型E E elementData(int index) { return (E) elementData[index]; }

三、null 值表示

  • 阿里巴巴开发手册强制规定

3.1 POJO 属性:用 null 强制提醒

如果一个订单的金额属性是 int,没有给它赋值,会使用默认值 0,变成“零元订单”,这个 Bug 很难发现。
但如果金额属性是 Integer,没有赋值它就是 null。当你后续使用它时,如果没有做非空判断,程序会立刻抛出 NullPointerException(NPE),强制性地提醒你:这里忘记赋值了,必须修复。

3.2 RPC 方法:用 null 表示调用失败

手册中举了一个反例:成交总额涨跌幅 x 如果用基本类型接收,当远程调用失败时,x 会被赋成默认值 0,页面就会显示“0%”,而正确做法应该是显示中划线。
包装类型的 null 恰好能承载“远程调用失败”这个额外信息,让调用方有机会区分“正常返回 0”和“调用出错了”。

3.3 Controller 方法参数:用 null 表示前端没传

  • 错误理解
    有人可能认为:基本数据类型默认值为 0,而包装类默认值为 null。所以在业务场景中,用户没填年龄,如果使用 Integer 就会传默认值 null;使用 int 就会传默认值 0。此时年龄应该用 null 表示,而 0 代表年龄为 0 岁不合适,所以我们要用包装类。
  • 正确理解
    1. 成员变量和局部变量的默认值规则完全不同
    成员变量:int 默认是 0,Integer 默认是 null。
    局部变量:必须显式初始化,没有默认值。
    但 Controller 方法的参数并不是类的成员变量,而是局部变量,需要由 Spring 从请求中绑定数据,没有默认值这一说。所以不能用“int 默认值是 0”来推断“前端不传参就能得到 0”。
    2. Spring 绑定参数
    当前端不传某个参数时,Spring 拿到的值是 null。
    - 如果使用基本类型,Spring 拿到的绑定值是 null,但 int 不是对象,没法接收 null,会直接抛出NPE异常;
    - 而使用包装类,Spring 可以将 null 正常绑定给包装类型,所以 age 为 null。
//报错:int不能存null int age = null; //Integer 可以存 null Integer age = null;

3. 配合动态 SQL,安全更新数据库

  • 错误写法
    如果前端没传这个参数,会直接把数据库里的 age 字段更新为 null,覆盖掉原来的值。
UPDATE User<set>age = #{age}</set>WHERE id = #{id}
  • 正确写法
    此时,age 为 null 时 if 条件不成立,不会更新年龄字段,完美保留了旧值。
UPDATE User<set><iftest="age != null">age = #{age}</if></set>WHERE id = #{id}

四、缓存机制

  • 作用
    包装类的缓存机制是为了优化性能和节省内存而设计的。
    它为整型(Byte、Short、Integer、Long)、字符型(Character)和布尔型(Boolean)的包装类都提供了缓存,创建这个范围的整数时,不会新建对象,而是直接返回缓存池里的同一个对象。
    而对于浮点数类型的包装类(Float、Double),则没有这种缓存机制,意味着每次都需要创建新的对象。

  • 使用条件
    该缓存池适用于调用了valueOf()方法产生的包装类对象,以及自动装箱的包装类对象;而不适用于new关键字创建的包装类对象。

  • 缓存范围
    Integer:-128 到 127
    Byte:-128 到 127
    Short:-128 到 127
    Character:0 到 127
    Boolean:true 和 false

Integer i1 = 127; Integer i2 = 127; System.out.println(i1 == i2);//true Integer i3 = 128; Integer i4 = 128; System.out.println(i3 == i4);//false //注意:用 equals 比较的是数值本身,无法体现是否是同一个对象 //而双等号== 比较的是地址,可以体现是同一个对象 System.out.println(i3.equals(i4));//true

拓展
自定义缓存的大小: 通过 JVM 参数-XX:AutoBoxCacheMax=size可以设置Integer缓存的最大值,最小缓存值固定为 -128,不可修改。

  1. 在当前文件下点击”编辑配置“

  2. 左侧选中你要运行的主类或Spring Boot 启动类。

  3. 点击修改选项,再点击添加虚拟机选项

  4. 名称中填类名,主类填完整类名(包括包名),虚拟机选项填-XX:AutoBoxCacheMax=最大值

  • 最后效果
Integer i1 = 128; Integer i2 = 128; System.out.println(i1 == i2);//true Short s1 = 128; Short s2 = 128; System.out.println(s1==s2);//false //AutoBoxCacheMax 只对 Integer 生效

五、类型转换

  • 把字符串数值转换成对应的基本数据类型
    八种包装类当中,除了 Character 都有对应的parseXxx的方法,进行类型转换。
    注意:字符串的内容必须是数字,如果是其它类型比如字母"abcd",则会报错。
String s1 = "666"; int i1 = Integer.parseInt(s1); int i2 = Integer.valueOf(s1); System.out.println(i1);//666 System.out.println(i2);//666 String s2 = "555.5"; double i3 = Double.parseDouble(s2); System.out.println(i3);//555.5
  • 把基本类型的数据转换成字符串
int i = 3; String s = Integer.toString(i);//"3" System.out.println(s+1);//"31" //拓展:转换成字符串的其它方法 int i = 3; //1. String s = i + ""; //2. String s = String.valueOf(i);

六、Character 类的方法

Character 没有 parseXxx,如果想将字符串类型的数据转换成 char 类型的数据,可以通过 String 类中的toCharArray()方法和charAt()方法实现。
除此之外,它还提供了一系列静态方法来判断字符类型和做大小写转换。

方法名说明
isDigit(char ch)是否是数字
isLetter(char ch)是否是字母
isLetterOrDigit(char ch)是否是字母或数字
isWhitespace(char ch)是否是空白字符(空格、tab、换行)
isUpperCase(char ch)是否是大写字母
isLowerCase(char ch)是否是小写字母
toUpperCase(char ch)转为大写字母
toLowerCase(char ch)转为小写字母
Character.isDigit('5'); // true Character.isLetter('a'); // true Character.isUpperCase('A'); // true Character.toLowerCase('Q'); // 'q'

七、Integer 类的方法

方法名说明
public static String toBinaryString(int i)返回无符号二进制字符串表示
public static String toOctalString(int i)返回无符号八进制字符串表示
public static String toHexString(int i)返回无符号十六进制字符串表示

八、数值常量

MAX_VALUE / MIN_VALUE

System.out.println(Integer.MAX_VALUE); // 2147483647 System.out.println(Integer.MIN_VALUE); // -2147483648 System.out.println(Double.MAX_VALUE); // 1.7976931348623157E308

九、包装类的注意事项

1. == 和 .equals():== 比较的是对象引用,.equals() 比较的是值。

2. 空指针异常(NullPointerException)

Integer num = null; int value = num; //抛出 NullPointerException

3. 性能开销: 装箱和拆箱涉及对象创建和方法调用,有性能开销。在性能敏感的循环中,应尽量避免不必要的装箱拆箱。

4. 内存占用:一个 Integer 对象比一个 int 占用多得多的内存(约 24 字节 vs 4 字节)。

总结

简单来说,对外输入输出的地方用包装类型,内部临时变量用基本类型。 有什么问题欢迎在评论区指出!!! 要是能点个赞我就更开心了^_^

http://www.jsqmd.com/news/763703/

相关文章:

  • 保姆级教程:用YOLOv8训练自己的动漫角色识别模型(从标注到部署)
  • Python 爬虫进阶技巧:网页压缩内容快速解压解析
  • 有没有完全免费去水印软件?效果好、无广告、不限次数实测合集 - 爱上科技热点
  • Python多准则决策分析库pyDecision:从AHP到TOPSIS的实战指南
  • 3分钟掌握M3U8视频下载的终极指南:N_m3u8DL-CLI-SimpleG
  • 【紧急预警】Dify金融问答正面临穿透式审计风暴:3类未记录prompt行为已触发监管问询!
  • 终极指南:如何用智能工具轻松管理Steam游戏破解流程
  • 2026办公神器:Gemini3.1Pro高效Prompt设计指南
  • VideoAgentTrek:无监督视频学习在AI操作技能中的应用
  • 2026 年 5 月国内外超声波液位差计十大品牌排名 - 仪表人小余
  • 别再瞎调权重了!Ceph集群数据分布不均?手把手教你读懂并优化Crush Map
  • PiliPlus:跨平台B站客户端,打造纯净无广告的观影体验
  • 函数式编程实现 - 学员管理系统 - 01
  • 永辉超市卡回收不踩坑!5种高效方法盘点,闲置卡快速变现超省心 - 京回收小程序
  • Modbus主站设备(Master)编程实战:用Python+pymodbus搞定128个从站轮询与避坑指南
  • 别再只抓HTTP了!用Wireshark过滤出纯‘以太网帧’,深入理解网络底层通信
  • MDB Tools终极指南:在Linux和macOS上高效处理Access数据库的完整解决方案
  • FITC标记的ROR1 Fc嵌合蛋白在肿瘤靶向治疗研究中的应用
  • 实测分享:真正免费且去水印效果好的软件,亲测好用无套路 - 爱上科技热点
  • Synology群晖歌词插件终极指南:5分钟为Audio Station添加QQ音乐智能歌词
  • 2026年江苏面粉加工设备采购指南:源头厂家直供方案与B端选型避坑手册 - 年度推荐企业名录
  • 不只是换皮肤:给你的Keil MDK换上仿VSCode主题,并深度定制字体与高亮
  • 5分钟掌握Reloaded-II:终极.NET Core游戏Mod加载器完整指南
  • 告别环境混乱:用Anaconda和PyCharm彻底解决Python包依赖冲突(以pandas为例)
  • 别再烧芯片了!用CH374/CH375做USB主机,必须知道的U盘热插拔保护电路设计
  • 智能图片去重工具AntiDupl.NET:3步高效清理重复图片,释放存储空间
  • 从IPPO到MAPPO:手把手教你用PyTorch实现多智能体协作(附Light-MAPPO代码实战)
  • 终极解决方案:如何修复TranslucentTB的Windows UI框架依赖问题
  • 2026 免费去水印软件盘点,效果好又免费,手机电脑都能用 - 爱上科技热点
  • 保姆级教程:用CUT模型搞定自制数据集风格迁移,从环境配置到避坑全记录