这是一个 Java 快速入门项目,非常适合用来练手。相关源码已上传至 GitHub,👉 点击查看 GitHub 仓库。欢迎交流指正、提交 issue。
Java 的 8 种基本类型 是值类型,不是对象,无法放入集合或直接调用方法。为此,每种基本类型都有对应的包装类,将其"包装"成对象,并支持 null 值、工具方法和自动装箱拆箱(Java 5+)。
一、基本类型 ↔ 包装类对照表
| 基本类型 | 包装类 | 示例 |
|---|---|---|
byte |
Byte |
Byte b = 127; |
short |
Short |
Short s = 1000; |
int |
Integer |
Integer i = 42; |
long |
Long |
Long l = 999L; |
float |
Float |
Float f = 3.14f; |
double |
Double |
Double d = 2.718; |
char |
Character |
Character c = 'A'; |
boolean |
Boolean |
Boolean b = true; |
二、核心作用
包装类的存在并非多余,它解决了基本类型在面向对象编程中的诸多局限。下面逐一说明其核心作用。
2.1 对象化 --- 放入集合
Java 集合框架(Collection、Map 等)只能存储对象,不能存储基本类型。包装类将基本类型"包装"成对象,使其能够放入集合中。
java
// 错误:List<int> list = new ArrayList<>(); // 编译错误
List<Integer> list = new ArrayList<>();
list.add(42); // 自动装箱,等价于 list.add(Integer.valueOf(42))
int val = list.get(0); // 自动拆箱,等价于 list.get(0).intValue()
同理,Map 的键值对也必须是对象:
java
Map<String, Double> scores = new HashMap<>();
scores.put("张三", 95.5);
scores.put("李四", 88.0);
2.2 工具方法 --- 丰富的静态工具
每个包装类都提供了大量静态方法和常量,极大方便了日常开发:
java
// 字符串 → 基本类型
int num = Integer.parseInt("123"); // 返回 int
Integer numObj = Integer.valueOf("123"); // 返回 Integer 对象
// 进制转换
String hex = Integer.toHexString(255); // "ff"
String bin = Integer.toBinaryString(10); // "1010"
// 常量
int maxInt = Integer.MAX_VALUE; // 2147483647
int minInt = Integer.MIN_VALUE; // -2147483648
int size = Integer.BYTES; // 4(占 4 字节)
// Character 的实用方法
boolean isDigit = Character.isDigit('9'); // true
boolean isLetter = Character.isLetter('A'); // true
char upper = Character.toUpperCase('a'); // 'A'
2.3 支持 null --- 表达"无值"语义
基本类型必须有一个默认值(如 int 默认为 0),无法区分"值为 0"和"没有值"。包装类允许 null,这在数据库字段、JSON 解析等场景中至关重要:
java
// 数据库查询:某个字段可能为 NULL
Integer age = resultSet.getObject("age", Integer.class);
// age 可能为 null(数据库 NULL)、也可能为具体数值
// 基本类型做不到
// int age = resultSet.getInt("age"); // 数据库 NULL 时返回 0,无法区分
再比如 JSON 反序列化:
java
// {"name":"张三","age":null}
// 用包装类可以正确表达"年龄未知"
public class User {
private String name;
private Integer age; // null 表示未填写年龄
}
2.4 字符串与基本类型互转
包装类提供了双向转换的桥梁,是数据解析和序列化的基础:
java
// 字符串 → 包装类 / 基本类型
Integer i1 = Integer.valueOf("100"); // 返回 Integer 对象
int i2 = Integer.parseInt("100"); // 返回 int 基本类型
Double d = Double.valueOf("3.14");
Boolean b = Boolean.valueOf("true"); // 忽略大小写,非"true"返回 false
// 基本类型 / 对象 → 字符串
String s1 = String.valueOf(100); // "100"
String s2 = Integer.toString(255, 16); // "ff"(转十六进制字符串)
String s3 = String.valueOf(3.14); // "3.14"
小结 :包装类的四大核心作用------对象化 让基本类型融入集合框架,工具方法 提供丰富的类型转换和判断能力,支持 null 弥补了基本类型无法表达"无值"的缺陷,字符串互转则是数据交换的基础。理解这些作用,就能明白为什么 Java 在保留基本类型的同时还要设计对应的包装类。
三、自动装箱与拆箱(Java 5+)
自动装箱(Autoboxing) 是指 Java 编译器自动将基本类型转换为对应的包装类对象,例如 int → Integer。
自动拆箱(Unboxing) 则相反,将包装类对象自动转换回基本类型,例如 Integer → int。
这一机制从 Java 5 开始引入,让基本类型和包装类之间的赋值、运算、方法传参等操作可以无缝进行,无需手动调用 valueOf() 或 xxxValue() 方法。
java
// 自动装箱:int → Integer
Integer i = 100; // 等价于 Integer.valueOf(100)
// 自动拆箱:Integer → int
int n = i; // 等价于 i.intValue()
编译器自动插入 valueOf() 和 xxxValue(),写法与基本类型一致。
四、注意事项
==比较陷阱 :比较的是引用,值相等应使用.equals()- 缓存机制 :
Integer默认缓存-128 ~ 127,范围内自动装箱复用同一对象。以下代码演示了缓存范围内外==与equals()的差异:
java
// 缓存范围内(-128 ~ 127)
Integer a = 100; // 自动装箱,复用缓存对象
Integer b = 100; // 自动装箱,复用同一缓存对象
System.out.println(a == b); // true (同一对象引用)
System.out.println(a.equals(b)); // true (值相等)
// 缓存范围外
Integer x = 200; // 自动装箱,创建新对象
Integer y = 200; // 自动装箱,创建另一个新对象
System.out.println(x == y); // false (不同对象引用)
System.out.println(x.equals(y)); // true (值相等)
原因 :Integer.valueOf() 方法内部维护了一个 IntegerCache,当传入的值在 -128 ~ 127 之间时,直接返回缓存中的对象;超出此范围则 new 一个新对象。因此 a == b 为 true(同一缓存对象),而 x == y 为 false(两个不同对象)。无论是否在缓存范围内,equals() 始终比较的是数值,结果均为 true。
- 性能开销:频繁装箱拆箱产生额外对象,大量循环中优先使用基本类型
包装类是基本类型与面向对象世界之间的桥梁,日常开发中非常常用。