20260729-笔记.md 5.4 KB

JavaSE 基础 — Day13 笔记

日期:2026-07-29
项目c260729
作者:WanJL


一、包装类(Wrapper Classes)

1.1 为什么需要包装类?

Java 中分为基本数据类型引用数据类型。Java 的核心思想是「万事万物皆为对象」,对象就一定有属性和方法。但 Java 中的 8 种基本数据类型(byteshortintlongfloatdoublecharboolean)是从 C/C++ 延续过来的,并不符合 Java 的面向对象特性——它们没有属性、也没有方法。

为了解决这个问题,Java 为每个基本数据类型都设置了对应的引用数据类型,即包装器类(Wrapper Classes)

📄 来源:Demo01.java

1.2 基本类型与包装类的对应关系

基本数据类型 包装器类(引用数据类型)
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

包装器类具有属性和方法,属于引用数据类型。

📄 来源:Demo01.java

1.3 装箱(Boxing)与拆箱(Unboxing)

装箱(Boxing):从基本数据类型 → 引用数据类型(包装类)
拆箱(Unboxing):从引用数据类型(包装类) → 基本数据类型

// 手动装箱(JDK9 前的方式,之后已标记为过时)
Integer integer = new Integer(a); // 装箱

// 自动装箱(JDK5+,推荐方式)
Integer i = a;       // int → Integer,自动装箱
Integer i1 = 15;     // 直接赋值,自动装箱

// 手动拆箱
int a1 = integer.intValue(); // 调用 intValue() 方法拆箱

// 自动拆箱(JDK5+,推荐方式)
int a2 = i;          // Integer → int,自动拆箱

📄 来源:Demo01.java

1.4 自动装箱与拆箱的底层原理

  • 自动装箱:编译器自动调用 Integer.valueOf(int) 方法
  • 自动拆箱:编译器自动调用 Integer.intValue() 方法
  • 自动装箱/拆箱机制从 JDK 5 开始引入

1.5 使用包装类的优势

  1. 拥有属性和方法:可以调用字符串解析、进制转换等方法
  2. 泛型支持:集合框架(如 ArrayList<Integer>)必须使用包装类,不能使用基本类型
  3. 允许 null:包装类属于引用类型,可以为 null,这在数据库映射等场景中很有用
  4. 工具方法:提供了丰富的静态工具方法(如 Integer.parseInt()Integer.valueOf() 等)

1.6 包装类在 Bean 类中的应用

在实际开发中,Bean 类(如 Person)的属性通常会使用包装类而非基本类型,原因包括:

  • 对象的属性可能为 null(数据库字段可为空)
  • 便于与泛型集合配合使用
  • 统一使用引用数据类型,符合 OOP 风格

    public class Person {
    private String name;
    private Integer age;  // 使用 Integer 而非 int,允许 age 为 null
        
    // getter / setter 方法
    }
    

📄 来源:Person.java

1.7 包装类的常用方法

Integer 为例,包装类提供了一些非常实用的静态方法:

方法 说明
Integer.parseInt(String s) 将字符串解析为 int
Integer.valueOf(int i) int 转换为 Integer(自动装箱底层调用)
Integer.valueOf(String s) 将字符串转换为 Integer
int Integer.intValue() Integer 转换为 int(自动拆箱底层调用)
Integer.MAX_VALUE int 的最大值(常量: 2147483647)
Integer.MIN_VALUE int 的最小值(常量: -2147483648)

其他包装类(DoubleBooleanCharacter 等)也有类似的方法。

1.8 包装类的缓存机制

部分包装类(IntegerByteShortLongCharacter)在自动装箱时存在缓存机制

  • Integer 缓存池:默认缓存 -128 ~ 127 范围的整数
  • 在此范围内,自动装箱复用同一个对象(== 比较为 true
  • 超出此范围,每次自动装箱都会新建对象

    Integer a = 100;  // 从缓存池获取
    Integer b = 100;  // 从缓存池获取
    System.out.println(a == b);  // true
    
    Integer c = 200;  // 超出缓存范围,新建对象
    Integer d = 200;  // 超出缓存范围,新建对象
    System.out.println(c == d);  // false
    
    // 推荐使用 equals() 比较包装类对象的值
    System.out.println(c.equals(d));  // true
    

注意:包装类对象的值比较应始终使用 equals() 方法,不要使用 ==


二、随堂练习要点

本日课程重点在于理解包装类的设计思想和使用方式:

  1. 概念理解:为什么 Java 需要包装类?基本类型和包装类各有什么优劣?
  2. 装箱/拆箱操作:手动 vs 自动,理解编译器的底层转换逻辑
  3. 实际应用:在 Bean 类中优先使用包装类(如 Integer 替代 int),便于表达 null 语义
  4. 常见陷阱
    • == 比较包装类时的缓存问题
    • 包装类对象参与算术运算时的自动拆箱
    • null 包装类拆箱会抛出 NullPointerException

三、拓展阅读