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

【从零开始java学习|第二十一篇】包装类是干嘛的

目录

一、包装类的定义与对应关系

关键分类:

二、包装类的核心作用

1. 适配对象场景(如集合、泛型)

2. 提供丰富的操作方法

3. 支持 null 值(区分 “无值” 与 “默认值”)

三、核心特性:自动装箱与自动拆箱

1. 自动装箱(基本类型 → 包装类)

2. 自动拆箱(包装类 → 基本类型)

3. 自动装箱的缓存机制

缓存规则:

缓存的影响:==比较的陷阱

关键结论:

四、包装类的常见问题与注意事项

1. 空指针异常(NPE)风险

2. 字符串转包装类的注意事项

3. 包装类的不可变性

五、包装类高频面试题

六、总结


在 Java 中,包装类是基本数据类型(如intchar)的 “对象化” 封装。由于 Java 是面向对象语言,许多场景(如集合框架、泛型)仅支持对象类型,不支持基本数据类型,包装类的核心作用就是 “桥梁”—— 将基本数据类型转换为对象,同时提供丰富的操作方法。

一、包装类的定义与对应关系

Java 为 8 种基本数据类型分别提供了对应的包装类,全部位于java.lang包下(无需手动导入),对应关系如下表:

基本数据类型包装类类型分类核心特点
byteByte整数型(小)占 1 字节,范围:-128~127
shortShort整数型(中)占 2 字节,范围:-32768~32767
intInteger整数型(常用)占 4 字节,范围:-2³¹~2³¹-1
longLong整数型(大)占 8 字节,范围:-2⁶³~2⁶³-1
floatFloat浮点型(单精度)占 4 字节,精度较低(约 6-7 位有效数字)
doubleDouble浮点型(双精度)占 8 字节,精度较高(约 15-17 位有效数字),常用
charCharacter字符型占 2 字节,存储 Unicode 字符
booleanBoolean布尔型仅存true/false,无明确字节数(JVM 实现不同)

关键分类:

  • 数值型包装类ByteShortIntegerLongFloatDouble,均继承自java.lang.Number类(提供intValue()longValue()等 “拆箱” 方法);
  • 非数值型包装类Character(继承自Object)、Boolean(继承自Object),无Number类的方法。

二、包装类的核心作用

包装类的设计初衷是解决 “基本数据类型无法直接参与面向对象操作” 的问题,核心作用可概括为 3 点:

1. 适配对象场景(如集合、泛型)

Java 集合框架(如ArrayListHashMap)和泛型仅支持对象类型,不支持基本数据类型。包装类可将基本数据类型 “包装” 为对象,使其能存入集合或作为泛型参数。

示例:基本类型 vs 包装类在集合中的使用

import java.util.ArrayList;public class WrapperCollectionTest {public static void main(String[] args) {// 错误:ArrayList不支持基本数据类型int// ArrayList<int> intList = new ArrayList<>();// 正确:使用包装类Integer,支持对象类型ArrayList<Integer> integerList = new ArrayList<>();integerList.add(10); // 自动装箱(int→Integer)integerList.add(20);// 取出时自动拆箱(Integer→int)int num = integerList.get(0);System.out.println(num); // 输出:10}
}

2. 提供丰富的操作方法

包装类内置了大量静态方法,用于基本数据类型的转换、比较、常量获取等操作,无需手动实现工具类。

常用方法示例(以Integer为例)

方法作用示例
parseInt(String s)将字符串转为 int(核心方法)Integer.parseInt("123") → 123
valueOf(int i)将 int 转为 Integer(缓存常用值)Integer.valueOf(10) → Integer对象
toString(int i)将 int 转为字符串Integer.toString(123) → "123"
MAX_VALUE/MIN_VALUE获取 int 的最大 / 最小值(静态常量)Integer.MAX_VALUE → 2147483647

实际应用:字符串转基本类型(如解析用户输入的数字字符串)

// 将前端传入的字符串"2024"转为int类型
String yearStr = "2024";
int year = Integer.parseInt(yearStr);
System.out.println(year + 1); // 输出:2025(可参与数值运算)

3. 支持 null 值(区分 “无值” 与 “默认值”)

基本数据类型有默认值(如int默认0boolean默认false),无法表示 “无值” 状态;而包装类是对象,可通过null表示 “无值”(如数据库字段的NULL值映射)。

示例:包装类表示 “无值”

// 场景:查询用户年龄,未查询到时返回null(而非默认0)
public class User {private Integer age; // 用包装类Integer,支持null// getter/setterpublic Integer getAge() { return age; }public void setAge(Integer age) { this.age = age; }
}public class WrapperNullTest {public static void main(String[] args) {User user = new User();user.setAge(null); // 未查询到年龄,设为null// 判断是否有值if (user.getAge() == null) {System.out.println("用户年龄未设置");} else {System.out.println("用户年龄:" + user.getAge());}}
}

三、核心特性:自动装箱与自动拆箱

Java 5 及以后引入自动装箱(Autoboxing) 和自动拆箱(Unboxing) 机制,消除了 “基本类型” 与 “包装类” 之间的手动转换代码,简化开发。

1. 自动装箱(基本类型 → 包装类)

定义:编译器自动将基本数据类型转换为对应的包装类对象,无需手动调用valueOf()方法。触发场景:将基本类型赋值给包装类变量、存入集合等。

// 手动装箱(Java 5前)
Integer num1 = Integer.valueOf(10);// 自动装箱(Java 5后,编译器自动补全valueOf())
Integer num2 = 10; // 等价于 Integer num2 = Integer.valueOf(10);// 集合中自动装箱
ArrayList<Integer> list = new ArrayList<>();
list.add(20); // 自动装箱:int 20 → Integer 20

2. 自动拆箱(包装类 → 基本类型)

定义:编译器自动将包装类对象转换为对应的基本数据类型,无需手动调用xxxValue()方法(如intValue())。触发场景:将包装类赋值给基本类型变量、参与数值运算、比较等。

// 自动拆箱:包装类 → 基本类型
Integer num3 = 30;
int num4 = num3; // 等价于 int num4 = num3.intValue();// 参与数值运算(自动拆箱)
int sum = num3 + 20; // 先拆箱为int 30,再计算 30+20=50
System.out.println(sum); // 输出:50// 比较(自动拆箱)
boolean isEqual = (num3 == 30); // 拆箱为int比较,结果为true

3. 自动装箱的缓存机制

为优化性能,整数型包装类(Byte、Short、Integer、Long) 和Character 提供了缓存机制—— 缓存常用值的包装类对象,避免重复创建,节省内存。

缓存规则:
包装类缓存范围说明
Byte-128 ~ 127全部缓存(范围固定)
Short-128 ~ 127固定范围缓存
Integer-128 ~ 127默认范围,可通过 JVM 参数调整上限
Long-128 ~ 127固定范围缓存
Character0 ~ 127缓存 ASCII 字符
Float/Double无缓存浮点型数值范围大,缓存无意义
缓存的影响:==比较的陷阱

缓存机制导致:缓存范围内的包装类对象,用==比较时返回 true(引用同一对象);超出范围则返回 false(新创建对象)

示例:缓存机制的实际影响

public class WrapperCacheTest {public static void main(String[] args) {// 1. 缓存范围内(-128~127):==比较引用,返回trueInteger a = 100;Integer b = 100;System.out.println(a == b); // true(同一缓存对象)// 2. 超出缓存范围:==比较引用,返回falseInteger c = 200;Integer d = 200;System.out.println(c == d); // false(新创建两个不同对象)// 3. 正确比较:用equals()(比较内容,而非引用)System.out.println(c.equals(d)); // true(内容都是200)// 4. 浮点型无缓存:==比较返回falseDouble e = 1.0;Double f = 1.0;System.out.println(e == f); // false(无缓存,新创建对象)}
}
关键结论:
  • 包装类比较必须用equals()方法(比较内容),不能用==(比较引用,受缓存影响);
  • 若包装类与基本类型用==比较,会触发自动拆箱(比较内容),结果正确(如Integer a=10; System.out.println(a==10); // true)。

四、包装类的常见问题与注意事项

1. 空指针异常(NPE)风险

包装类可能为null,自动拆箱时若包装类对象为null,会抛出NullPointerException(NPE),需特别注意。

示例:空指针异常场景

public class WrapperNpeTest {public static void main(String[] args) {Integer num = null; // 包装类为null// 错误:自动拆箱时null无法转为int,抛出NPE// int value = num; // 正确:先判断非null,再拆箱if (num != null) {int value = num;System.out.println(value);} else {System.out.println("包装类对象为null");}}
}

2. 字符串转包装类的注意事项

parseXXX(String s)valueOf(String s)将字符串转为包装类时,需确保字符串是合法的数值格式,否则抛出NumberFormatException

// 正确:字符串是合法整数
int num1 = Integer.parseInt("123");// 错误:字符串包含非数字字符,抛出NumberFormatException
// int num2 = Integer.parseInt("123a");// 错误:空字符串,抛出NumberFormatException
// int num3 = Integer.parseInt("");

3. 包装类的不可变性

所有包装类都是不可变类—— 对象创建后,其内部存储的基本数据类型值无法修改(无setter方法)。若需修改值,只能创建新的包装类对象。

Integer num = 10;
num = 20; // 并非修改原对象,而是创建新的Integer(20)对象,num引用指向新对象

五、包装类高频面试题

  1. Java 为什么需要包装类?答:解决基本数据类型无法参与面向对象操作的问题(如集合、泛型仅支持对象);提供丰富的数值操作方法;支持null值(区分 “无值” 与默认值)。

  2. 自动装箱和自动拆箱的原理是什么?答:自动装箱是编译器自动调用valueOf()将基本类型转为包装类;自动拆箱是编译器自动调用xxxValue()(如intValue())将包装类转为基本类型。

  3. Integer a=100, b=100; a==b 返回 true;a=200, b=200; a==b 返回 false,为什么?答:Integer 有缓存机制,默认缓存 - 128~127 的对象。100 在缓存范围内,a 和 b 引用同一缓存对象,==返回 true;200 超出范围,需新创建对象,==比较引用不同,返回 false。

  4. 包装类比较用 == 还是 equals ()?为什么?答:必须用equals()==比较引用地址(受缓存影响,超出范围会返回 false);equals()重写后比较内容(如 Integer 的 equals () 比较 int 值),结果正确。

  5. 包装类可能引发 NullPointerException 吗?什么时候?答:可能。当包装类对象为null,触发自动拆箱(如赋值给基本类型、参与运算)时,会抛出 NPE。

六、总结

包装类是 Java 连接 “基本数据类型” 与 “面向对象特性” 的核心桥梁,核心要点可概括为:

  1. 对应关系:8 种基本类型对应 8 种包装类,数值型继承Number,非数值型继承Object
  2. 核心作用:适配集合 / 泛型、提供操作方法、支持null值;
  3. 关键特性:自动装箱(valueOf())与拆箱(xxxValue())、整数型 / Character 的缓存机制;
  4. 避坑要点:用equals()比较内容、避免null拆箱引发 NPE、字符串转包装类需校验格式。

如果我的内容对你有帮助,请点赞,评论,收藏。接下来我将继续更新相关内容!

http://www.dtcms.com/a/428769.html

相关文章:

  • 网站建设运营协议书子公司网站备案
  • 晋江市建设招投标网站自己怎么制作网页游戏
  • 衡水建立网站关键词排名优化易下拉稳定
  • 国外网站建设软件排行榜h5快速建站
  • 长沙 php企业网站系统一个公司可以备案几个网站
  • 基本信息型网站有哪些爱做网站免费模板vip
  • 咖啡网站设计模板河北手机版建站系统开发
  • 什么是烟雾病?从症状识别到治疗选择
  • C++内存泄漏排查:从基础到高级的完整工具指南
  • [MT6835] MT6835如何通过指令判断secureboot是否开启
  • 互联网信息服务算法备案深度解析:从适用对象到风险警示的科普指南
  • svn: E160028
  • 网站放到云服务器上怎么做哪个网站可以做砍价
  • Memcached 安装与服务管理指南
  • 少年三国志(本地部署游玩)
  • 凡科做网站不好网络服务公司
  • 闲置tp路由自己做网站怎么在国税网站上做实名认证吗
  • 呼市賽罕区信息网站做一顿饭工作安徽六安
  • 手机评测网站设计师网单怎么做
  • sshd 启动失败问题排查总结(没有core)
  • 网站的页面由什么组成中铁建设集团有限公司招聘官网
  • 【Rust GUI开发入门】编写一个本地音乐播放器(7. 制作歌词显示面板)
  • dedecms做地方网站中建八局第二建设有限公司
  • 胶州网站建设平台外贸出口新三样
  • TransmittableThreadLocal(父子线程传递ThreadLocal)
  • 做的比较漂亮的网站门户网站编辑流程
  • 北京通网站建设一 网站建设方案
  • 网线介绍、家庭测网速方法、网线接法、水晶头接法
  • 大连凯杰建设有限公司网站seo培训班 有用吗
  • 高斯包络调制正弦波的Python代码