基本类型与包装类

核心概念

Java提供了8种基本数据类型用于存储原始数据,同时为每种基本类型提供了对应的包装类,使其能参与面向对象编程。


一、8种基本数据类型

1.1 类型总览

分类 类型 字节 取值范围 默认值
整型 byte 1 -128 ~ 127 0
short 2 -32,768 ~ 32,767 0
int 4 -2³¹ ~ 2³¹-1 (约±21亿) 0
long 8 -2⁶³ ~ 2⁶³-1 0L
浮点型 float 4 IEEE 754单精度 (6-7位) 0.0f
double 8 IEEE 754双精度 (15位) 0.0d
字符型 char 2 0 ~ 65,535 (Unicode) '\u0000'
布尔型 boolean 未规定 true/false false

1.2 特殊说明

boolean的大小问题

boolean理论上1个bit就够,但JVM实际处理:
1. 单独变量:通常占1字节
2. 编译时转换:用int表示(1=true, 0=false3. boolean数组:通过byte数组实现

为什么不规定大小?

  • JVM规范未强制,给不同实现留空间
  • 单变量用1字节对齐效率高
  • 数组场景按 byte 数组实现(1 元素 1 字节);bit 级压缩交给 java.util.BitSet 这类工具类

char与C++的区别

Java: 2字节,存储Unicode字符
char c = '中';  // 支持中文

C++: 1字节(语言规定 sizeof(char) 恒等于 1char c = 'A';   // 1字节可承载 ASCII/UTF-8 字节
wchar_t wc = L'中';  // 宽字符,宽度随平台(Windows 2字节、Linux 4字节)

char 的 Unicode 陷阱

// char 范围:0-65535(16位)
char c1 = '中';  // ✅ BMP 字符(U+0000 ~ U+FFFF)
char c2 = 0x1F600;  // ❌ 编译错误(Emoji 超出范围)

// Unicode 补充字符(需要 2 个 char)
String emoji = "😀";
System.out.println(emoji.length());  // 2(不是 1!)
System.out.println(emoji.codePointCount(0, emoji.length()));  // 1 ✅


// 1. 一个 char 能存储所有 Unicode 字符吗?❌
// 2. String.length() 返回的是什么?(char 数量,非字符数)
// 3. 如何正确遍历字符串?(使用 codePoints())

二、包装类(Wrapper Class)

2.1 为什么需要包装类?

核心原因:基本类型不是对象,无法参与面向对象编程

// ❌ 编译错误:集合只能存对象
List<int> list = new ArrayList<>();

// ✅ 正确:使用包装类
List<Integer> list = new ArrayList<>();

2.2 基本类型与包装类对应关系

基本类型 包装类 父类
byte Byte Number
short Short Number
int Integer Number
long Long Number
float Float Number
double Double Number
char Character Object
boolean Boolean Object

继承体系:

Object
├── Number (抽象类)
│   ├── Byte
│   ├── Short
│   ├── Integer
│   ├── Long
│   ├── Float
│   └── Double
├── Character
└── Boolean

2.3 包装类的核心特性

① 不可变性(Immutable)

Integer a = 10;
a = 20;  // 不是修改原对象,而是创建新对象

② 提供工具方法

// 类型转换
int i = Integer.parseInt("123");
String s = Integer.toString(456);

// 进制转换
String binary = Integer.toBinaryString(10);  // "1010"
String hex = Integer.toHexString(255);       // "ff"

// 比较方法
int result = Integer.compare(10, 20);        // -1

③ 常量定义

Integer.MAX_VALUE   // 2147483647
Integer.MIN_VALUE   // -2147483648
Integer.SIZE        // 32 (位数)
Integer.BYTES       // 4 (字节数)

三、基本类型 vs 包装类

3.1 核心区别

对比维度 基本类型 包装类
存储位置 栈内存 堆内存(对象)
默认值 有(如int为0) null
性能 高(直接操作值) 低(对象开销)
空值支持 不支持 支持null
集合支持 不支持 支持
方法调用 不支持 支持

3.2 使用场景选择

// ✅ 优先使用基本类型(性能优先)
public void calculate(int count) {
    for (int i = 0; i < count; i++) {
        // 高频运算
    }
}

// ✅ 必须用包装类的场景
List<Integer> list = new ArrayList<>();  // 集合
Map<String, Long> map = new HashMap<>(); // 泛型

// ✅ 可能为null的场景用包装类
public Integer getUserAge(String userId) {
    User user = findUser(userId);
    return user != null ? user.getAge() : null;  // null表示未找到
}

// ❌ 避免混用导致性能问题
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
    list.add(i);  // 频繁装箱,创建10000个Integer对象
}

四、与C/C++的关键区别

4.1 固定大小 vs 平台相关

// Java: int永远是4字节(跨平台一致)
int i = 10;

// C++: int可能是2或4字节(取决于平台)
// int i = 10;  // 在32位系统可能是4字节,16位系统可能是2字节

4.2 空值支持

// Java: 基本类型不能为null
int x = null;  // ❌ 编译错误

Integer y = null;  // ✅ 包装类可以

// C++: 可通过指针实现
// int* p = nullptr;  // ✅ 指针可为空

4.3 默认值

// Java: 成员变量有默认值
class Demo {
    int count;     // 自动初始化为0
    boolean flag;  // 自动初始化为false
}

// Java: 局部变量必须显式初始化
void method() {
    int x;
    System.out.println(x);  // ❌ 编译错误:未初始化
}

// C++: 都不会自动初始化(未定义行为)

五、高频面试题

Q1: Java有哪些基本数据类型?各占多少字节?

答: 8种:

  • 整型:byte(1)、short(2)、int(4)、long(8)
  • 浮点:float(4)、double(8)
  • 字符:char(2)
  • 布尔:boolean(未规定,通常1字节)

Q2: 为什么Java要设计基本类型和包装类型?

答:

  1. 性能考虑:基本类型直接存储值,运算效率高
  2. 对象化需求:集合、泛型必须用对象
  3. 功能扩展:包装类提供工具方法(如parseInt)
  4. 兼容设计:保留C/C++的高性能特性,又支持面向对象

Q3: int和Integer有什么区别?分别适用于哪些场景?

答:

  • int:基本类型,性能高,不能为null,适合高频计算
  • Integer:对象类型,功能丰富,可为null,适合集合、泛型

场景选择:

// 优先int:循环、运算、局部变量
for (int i = 0; i < 10000; i++) { }

// 必须Integer:集合、泛型、可能为null
List<Integer> list = new ArrayList<>();

Q4: List<int> 为什么不合法?怎么解决?

答:

  • 原因:泛型要求类型参数必须是对象,int不是对象
  • 解决:使用包装类 List<Integer>
  • 性能优化:元素量大、性能敏感的场景改用基本类型数组 int[](从 Java 1.0 起就可用,与任何 JDK 版本无关),或引入 fastutil / Eclipse Collections 这类提供 IntList 的基本类型集合库,省掉每个元素的包装对象开销

Q5: 为什么char在Java中占2字节,而C++中占1字节?

答:

  • Java:char 是 UTF-16 的编码单元,固定 2 字节——一个 char 装一个 UTF-16 码元,天然覆盖中文等 BMP 字符;Emoji 等增补字符需要两个 char(代理对)
  • C++:1 字节是语言规定(sizeof(char) 恒等于 1,字节的位数由实现决定、通常为 8),ASCII 和 UTF-8 字节都用它承载,与"只支持英文"无关
  • 扩展:C++ 需要更宽的字符类型时用 wchar_t(宽度随平台:Windows 2 字节、Linux 4 字节);要定宽可移植就用 C++11 的 char16_t / char32_t

相关链接


记忆口诀

8种基本类型:

四整两浮一字符,布尔独立记心间 byte short int long,float double细分辨 char支持万国码,boolean真假判

包装类命名:

六个Number是数字,Character字符独,Boolean布尔殊 Integer特别记,其余首字母大写即可


⬅️ 基础概览 🏠 00-Java ➡️ 自动装拆箱