Java中的数据类型分类
Java中的数据类型分为基本数据类型和引用数据类型。
基本数据类型(Primitive Types)
Java 中预定义的 8 种最基础的数据类型,它们直接表示一个具体的值。
| 类型 | 关键字 | 大小 | 示例 |
|---|---|---|---|
| 整型 | byte |
1 字节 | 127 |
| 整型 | short |
2 字节 | 32000 |
| 整型 | int |
4 字节 | 100 |
| 整型 | long |
8 字节 | 100L |
| 浮点型 | float |
4 字节 | 3.14f |
| 浮点型 | double |
8 字节 | 3.14 |
| 字符型 | char |
2 字节 | 'A' |
| 布尔型 | boolean |
未明确定义 | true |
特点: 变量名直接对应 数值本身,创建时不需要 new。
java
int age = 25; // age 就是 25 本身
char grade = 'A'; // grade 就是 'A' 本身
引用数据类型(Reference Types)
除了 8 种基本类型外,所有其他类型都是引用数据类型,包括:
- 类(Class):
String、Person、Scanner等 - 接口(Interface):
List、Runnable等 - 数组(Array):
int[]、String[]等 - 枚举(Enum): 自定义枚举类型
特点: 变量名保存的是对象的内存地址 ,需要通过 new 关键字创建对象。
java
String name = new String("张三"); // name 存的是"张三"这个对象在堆里的地址
int[] arr = new int[3]; // arr 存的是数组对象在堆里的地址
Person p = new Person(); // p 存的是 Person 对象的地址
为什么要有这种区分?
这是 Java 性能与面向对象设计之间的权衡,核心原因有三个:
1. 性能优化 ------ 基本类型更快
堆内存(对象)的创建、访问和回收成本远高于栈内存。对于高频使用的小数据 (如循环计数器的 int i),如果也用对象创建,性能会大幅下降。
java
// 如果 int 也是对象:
Integer i = new Integer(0); // 堆分配、GC回收 → 慢
i = i + 1; // 拆箱+装箱 → 更慢
// 但实际 int 是这样的:
int i = 0; // 栈直接存储 → 极快
i++;
2. 内存效率 ------ 基本类型更省空间
| 类型 | 基本类型(栈) | 包装类对象(堆) |
|---|---|---|
int |
4 字节 | 16~24 字节(对象头+数据+对齐) |
boolean |
1 字节 | 16~24 字节 |
对象在堆中除了数据本身,还要额外存储对象头(标记字、类指针等),占用更多内存。
3. 语义区分 ------ 明确值的含义
- 基本类型 = 没名字的"值本身"(好比「数字 5」)
- 引用类型 = 有身份的对象(好比「名叫张三的人」)
java
int a = 5;
int b = a; // a 和 b 完全独立,修改 b 不影响 a
String s1 = new String("Hi");
String s2 = s1; // s1 和 s2 指向同一个对象,修改会影响另一个
这种区分让程序员能明确知道 赋值是"值拷贝"还是"地址拷贝",避免混淆。
总结
| 基本类型 | 引用类型 | |
|---|---|---|
| 本质 | 直接存"值" | 存"对象的地址" |
| 存储 | 栈 | 栈存地址,堆存数据 |
| 性能 | 快、省内存 | 慢、占内存 |
| 典型场景 | 数字计算、循环控制 | 复杂对象、集合、字符串 |
Java 的设计哲学就是:
把常见的"小数据"做成基本类型追求性能,把"大数据/复杂结构"做成引用类型追求面向对象的灵活性。两者互补,各司其职。