8种基本数据类型
Java 有 8种基本数据类型,而它们都不是对象:
| 类型 | 大小 | 取值范围 | 默认值 |
|---|---|---|---|
byte |
8位 | -128 ~ 127 | 0 |
short |
16位 | -32,768 ~ 32,767 | 0 |
int |
32位 | -2³¹ ~ 2³¹-1 | 0 |
long |
64位 | -2⁶³ ~ 2⁶³-1 | 0L |
float |
32位 | IEEE 754 浮点数 | 0.0f |
double |
64位 | IEEE 754 浮点数 | 0.0d |
char |
16位 | '\u0000' ~ '\uffff' | '\u0000' |
boolean |
1位 | true/false | false |
为什么设计这8种基本类型?
- 性能考虑
java
// 基本类型 - 直接在栈上分配,高效
int a = 10;
int b = 20;
int c = a + b; // 直接在CPU寄存器中操作
// 如果使用对象 - 需要在堆上分配,有对象头开销
Integer x = Integer.valueOf(10); // 堆内存分配
Integer y = Integer.valueOf(20);
Integer z = Integer.valueOf(x.intValue() + y.intValue());
- 内存效率
java
// 基本类型数组 - 内存紧凑
int[] array = new int[1000];
// 总内存: 1000 * 4字节 = 4KB
// 对象类型数组 - 内存分散
Integer[] array = new Integer[1000];
// 总内存: 1000个对象引用 + 每个Integer对象的内存开销
int[1000]的内存:

Integer[1000]的内存:

装箱和拆箱(Boxing & Unboxing)
- 什么是装箱拆箱?
java
// 自动装箱:基本类型 → 包装类型
int primitive = 42;
Integer boxed = primitive; // 自动装箱
Integer manualBox = Integer.valueOf(primitive); // 手动装箱
// 自动拆箱:包装类型 → 基本类型
Integer boxed = Integer.valueOf(100);
int unboxed = boxed; // 自动拆箱
int manualUnbox = boxed.intValue(); // 手动拆箱
- 在集合中的问题
java
List<Integer> list = new ArrayList<>();
// 每次 add 都发生装箱
list.add(1); // 装箱:int → Integer
list.add(2); // 装箱:int → Integer
// 每次 get 都发生拆箱
int first = list.get(0); // 拆箱:Integer → int
// 等价于:
list.add(Integer.valueOf(1));
int first = list.get(0).intValue();
包装类型
每个基本类型都有对应的包装类:
| 基本类型 | 包装类 | 缓存范围 |
|---|---|---|
byte |
Byte |
-128 ~ 127 |
short |
Short |
-128 ~ 127 |
int |
Integer |
-128 ~ 127 |
long |
Long |
-128 ~ 127 |
float |
Float |
无缓存 |
double |
Double |
无缓存 |
char |
Character |
0 ~ 127 |
boolean |
Boolean |
true, false |
为什么泛型不能直接使用基本类型?
- 类型擦除的限制
java
// 这是不允许的!
List<int> list = new ArrayList<int>(); // 编译错误!
// 只能使用包装类型
List<Integer> list = new ArrayList<Integer>(); // 正确
原因:Java 泛型在编译后会被擦除,所有泛型参数都变成 Object。而基本类型不是 Object 的子类。
如何选择
性能敏感场景要避免装箱
java
// 不好的做法 - 大量装箱开销
HashMap<Integer, String> map = new HashMap<>();
for (int i = 0; i < 1000; i++) {
map.put(i, "value" + i); // 每次 put 都装箱
}
// 好的做法 - 使用 SparseArray 避免装箱
SparseArray<String> sparseArray = new SparseArray<>();
for (int i = 0; i < 1000; i++) {
sparseArray.put(i, "value" + i); // 无装箱
}