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

【Java SE】包装类(Wrapper Class)

包装类

  • 什么是包装类?
  • 为什么需要包装类?
      • 1. 泛型与集合的必需品
      • 2. 对象方法的调用
      • 3.实体类(POJO)中使用包装类
  • 装箱与拆箱⭐
    • 手动 装箱/拆箱
    • 自动 装箱/拆箱
    • valueOf() 源码分析(包装类缓存池) ⭐
    • 包装类在集合中的应用与性能考量
      • 开销分析 ⭐
      • 性能对比测试
    • null 拆箱引发的 NPE
    • 包装类与基本类型的比较

在Java中,有一句广为流传的名言:“万物皆对象”。然而,这句话其实并不完全准确。因为我们还有8个“异类”——intdoubleboolean等基本数据类型。它们不是对象,无法调用方法,也无法在集合中存储。

为了解决这个问题,包装类应运而生。它们就像给基本数据类型穿上了一件“对象的外衣”。

什么是包装类?

包装类是Java为每种基本数据类型提供的对应的引用类型。

基本类型包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

注意:除了IntegerCharacter,其他包装类的名字与基本类型名首字母大写即可。

为什么需要包装类?

1. 泛型与集合的必需品

Java的泛型不支持基本类型。如果想创建一个ArrayList来存储整数,必须使用ArrayList<Integer>。如果试图写ArrayList<int>,编译器会直接报错。

2. 对象方法的调用

包装类提供了许多实用的静态方法,方便类型转换。

// 将字符串转换为整数intnum=Integer.parseInt("123");// 将整数转换为二进制字符串Stringbinary=Integer.toBinaryString(10);// 输出 "1010"

3.实体类(POJO)中使用包装类

在领域模型中,建议使用包装类。

  • 数据库的字段可能是NULL,映射到int会变成0,产生业务歧义。
  • 使用Integer可以完美区分“未设置”和“设置为0”。

装箱与拆箱⭐

  • 装箱:将基本类型转换为包装类对象。
  • 拆箱:将包装类对象转换为基本类型。

手动 装箱/拆箱

inta=10;Integernum=Integer.valueOf(a);// 手动装箱intb=num.intValue();// 手动拆箱doublec=num.doubleValue();

自动 装箱/拆箱

Integernum=10;// 自动装箱:相当于 Integer.valueOf(10)intd=num;// 自动拆箱:相当于 num.intValue()

valueOf() 源码分析(包装类缓存池) ⭐

这是包装类中最容易出错,也是面试中最常考的点:缓存池
我们来看一段代码:

Integera=100;Integerb=100;System.out.println(a==b);// 输出 true 还是 false?Integerc=200;Integerd=200;System.out.println(c==d);// 输出 true 还是 false?

运行结果:

true false

为什么呢?ctrl+B看看valueOf()源码

publicstaticIntegervalueOf(inti){if(i>=IntegerCache.low&&i<=IntegerCache.high)returnIntegerCache.cache[i+(-IntegerCache.low)];returnnewInteger(i);}

使用自动装箱(Integer.valueOf())时,JVM为了提高性能和节省内存,会对特定范围内的数值进行缓存

  • IntegerCache.lowstatic final int low = -128
  • IntegerCache.highstatic final int high= 127
  • 代码逻辑
    • 如果i的值在[-128, 127]之间,valueOf()方法会直接从缓存数组中返回同一个Integer对象
    • 如果超出这个范围,则new一个新的Integer对象

在例子中,ab都指向缓存中的同一个对象,所以==比较内存地址返回true。而cd是两个不同的对象,返回false

注意==比较的是内存地址(引用),比较数值请使用equals()方法。

更多补充:缓存池和常量池的区别

包装类在集合中的应用与性能考量

开销分析 ⭐

虽然包装类很方便,但在高频数据计算中,它带来了额外的性能开销。

// 性能较差的写法Integersum=0;// Integer sum = Integer.valueOf(0);for(inti=0;i<10000;i++){sum+=i;// sum = Integer.valueOf(sum.intValue() + i);// 这里每次循环都发生了:拆箱 -> 计算 -> 装箱}

10000次循环会创建约10000个Integer对象(实际上因为缓存机制,0-127范围内的值可能复用,但整体数量依然很大)。这会增加GC(垃圾回收)的压力。在高性能场景下,优先使用基本类型int进行计算。

性能对比测试

publicclassPerformanceTest{// 使用包装类publicstaticvoidtestWrapper(){longstart=System.nanoTime();Integersum=0;for(inti=0;i<10000000;i++){// 1000万次sum+=i;}longend=System.nanoTime();System.out.println("包装类耗时: "+(end-start)/1000000+" ms");}// 使用基本类型publicstaticvoidtestPrimitive(){longstart=System.nanoTime();intsum=0;for(inti=0;i<10000000;i++){sum+=i;}longend=System.nanoTime();System.out.println("基本类型耗时: "+(end-start)/1000000+" ms");}publicstaticvoidmain(String[]args){testPrimitive();// 输出: 基本类型耗时: 5 mstestWrapper();// 输出: 包装类耗时: 43 ms}}

null 拆箱引发的 NPE

自动拆箱时,如果包装类对象为null,会抛出NullPointerException

Integernum=null;inti=num;// 报错! 相当于执行了 num.intValue()

建议修改为

Integerx=null;inty=(x==null)?0:x;

包装类与基本类型的比较

当包装类与基本类型使用==比较时,包装类会自动拆箱为基本类型,此时比较的是数值,而不是地址。

inta=10;Integeri=newInteger(100);intj=100;System.out.println(i==j);// 输出 true (因为i自动拆箱了)
  • 装箱/拆箱是基本类型包装类之间的转换。
  • JDK 1.5+ 的自动装箱/拆箱是编译器语法糖,本质是调用valueOf()xxxValue()
  • 常见坑:Integer==(缓存范围导致结果“看起来不一致”)以及null拆箱导致 NPE。
http://www.jsqmd.com/news/545697/

相关文章:

  • Llama-3.2V-11B-cot部署教程:修复致命视觉权重Bug+开箱即用方案
  • 告别文献标签混乱:3步解锁Zotero效率工具的自动化管理方案
  • DeepChat一键启动揭秘:Llama3:8b镜像免配置部署教程(含端口自愈与模型缓存)
  • 注意力机制融合新范式:从GCNet与DANet看全局建模的演进与实战
  • 基于MATLAB的FFT滤波技术:实现波形数据谐波分析、频段清除与提取的全面解决方案
  • STP安全特性实战:如何用bpduguard和bpdufilter防止网络攻击(附真实案例)
  • 爬取并保存图片资源(正则方法)
  • 从燃油车到智能座舱:AUTOSAR网络管理在车载以太网时代面临的挑战与适配
  • 嵌入式热敏电阻温度解算:纯整数查表与插值算法
  • ESLyric歌词源配置指南:实现多平台歌词格式兼容与高效解析
  • 儒学之困、道家之远、佛学之迷:当代中国人精神生活的三幅面孔 ——基于自感痕迹论的文化诊断
  • 如何通过AI技术提升足球战术分析效率?
  • 海康MVS相机+Halcon标定实战:18张图搞定畸变矫正(附标定板选购指南)
  • WiFi CSI感知技术完全指南:从信号到智能环境的革命
  • Dual-Tree Agent RAG:可控、可解释、可验证
  • HunyuanVideo-Foley实战案例:电商产品视频+定制化音效一体化生成方案
  • Spring Boot 3.2项目实战:5分钟搞定Tomcat虚拟线程配置,让你的接口吞吐量翻倍
  • Html2Pdf:解决PHP环境下HTML转PDF难题的智能方案
  • 打造沉浸式智能AI问答助手:Vue3 + UniApp 全端实战(支持 Markdown/公式/多模态交互)
  • Chord视频理解工具实际应用:保险定损视频破损区域定位+程度分级时间轴
  • SDMatte Web端体验优化:首屏加载速度与模型预热机制说明
  • 计算机网络 之 【网络套接字编程】(固定宽度整数类型、socket常见API、netstat)
  • LFM2.5-1.2B-Thinking-GGUF惊艳效果:32K上下文下长篇技术方案生成质量
  • 为什么你的NDVI计算总是偏差±0.15?3个浮点精度陷阱+2种科学级校准方案(中科院遥感所验证版)
  • 别再ping IP了!手把手教你给ZeroTier虚拟网络里的设备起个‘好记’的名字(DNS/mDNS实战)
  • 告别单打独斗!Apipost 8协作版数据迁移保姆级教程(含团队项目处理)
  • 2026更新版!AI论文软件测评:最新工具推荐与对比分析
  • 新手福音:在快马平台零基础上手加速库,轻松提速深度学习训练
  • .NET代码混淆终极指南:用Obfuscar全面保护你的应用程序
  • SAP资产主数据批量修改避坑大全:GGB1替代+AR31工作清单配置详解(含日期字段特殊处理)