Java中各种类型的数据都存放在哪里
这是一个非常核心、而且一旦理解就“打通任督二脉”的问题。
下面我会用 “分类 + 场景 + 画面感” 的方式,把 Java 中所有常见数据类型放在哪里讲清楚,而且不靠黑话、不靠 JVM 术语堆砌。
你只需要记住一句话作为主线:
“变量在哪,值(或引用)就在哪;对象永远在堆里。”
一、先给一张“总地图”(一定先看)
Java 内存(从程序员视角)主要分为三大块:
┌──────────────┐
│ 方法区 / 元空间 │ ← 类信息、方法、静态变量
└──────────────┘
┌──────────────┐
│ 堆 │ ← 所有对象、数组
└──────────────┘
┌──────────────┐
│ 栈 │ ← 方法调用、局部变量
└──────────────┘
二、基本数据类型(8 种)
int, long, short, byte
float, double
char
boolean
1️⃣ 作为【局部变量】时
void f() {
int a = 10;
double b = 2.5;
}
📍 存放位置:栈
栈帧(f)
├── a = 10
└── b = 2.5
✔ 值直接存
✔ 随方法结束自动销毁
✔ 不经过 GC
2️⃣ 作为【成员变量】时
class A {
int x = 10;
}
📍 存放位置:堆(对象内部)
堆
└── A对象
└── x = 10
✔ 跟着对象一起生死
✔ 有默认值
3️⃣ 作为【静态变量】时
class A {
static int y = 20;
}
📍 存放位置:方法区 / 元空间
方法区
└── A.class
└── y = 20
✔ 全类唯一
✔ 类加载时创建
三、引用类型(对象、数组、接口等)
1️⃣ 对象本体(永远不变)
new Object();
new String("abc");
new int[10];
📍 一定在堆中
❗ 这是 Java 中唯一绝对成立的规则
2️⃣ 引用变量放哪,取决于“它声明在哪里”
① 局部引用变量
void f() {
Object o = new Object();
}
📍 引用在:栈
📍 对象在:堆
栈 堆
o ───────▶ Object实例
② 成员引用变量
class A {
Object o = new Object();
}
📍 引用在:堆(A对象内部)
📍 对象在:堆
堆
A对象
└── o ─────▶ Object对象
③ 静态引用变量
class A {
static Object o = new Object();
}
📍 引用在:方法区
📍 对象在:堆
四、数组(特殊但很好理解)
1️⃣ 数组对象本身
int[] arr = new int[5];
📍 数组对象:堆
堆
└── int[5]
2️⃣ 数组引用变量
- 局部数组变量 → 栈
- 成员数组变量 → 堆
- 静态数组变量 → 方法区
3️⃣ 数组元素存哪?
基本类型数组
int[] arr = {1, 2, 3};
📍 值直接存在数组对象里(堆)
引用类型数组
Object[] arr = new Object[3];
堆
arr
├── ref ─▶ Object
├── ref ─▶ Object
└── ref ─▶ null
五、String(面试最爱)
1️⃣ 字符串字面量
String s = "abc";
📍 "abc" 在:字符串常量池(堆的一部分)
📍 s 在:栈
2️⃣ new String()
String s = new String("abc");
堆
├── 常量池:"abc"
└── String对象
六、方法、类、代码放哪?
1️⃣ 方法本身
void f() {}
📍 方法区 / 元空间
2️⃣ 类信息
class A {}
📍 方法区 / 元空间
3️⃣ 方法执行时的数据
f();
📍 栈帧(栈)
七、包装类型(Integer 等)
Integer x = 10;
📍 x → 栈
📍 Integer(10) → 堆(可能来自缓存)
包装类 ≠ 基本类型
八、用一张“终极对照表”收尾
| 数据类型 | 存放位置 |
|---|---|
| 局部基本类型 | 栈 |
| 成员基本类型 | 堆 |
| 静态基本类型 | 方法区 |
| 对象 / 数组 | 堆 |
| 局部引用 | 栈 |
| 成员引用 | 堆 |
| 静态引用 | 方法区 |
| 方法 / 类元数据 | 方法区 |
| String 常量 | 堆(常量池) |
九、一句“能应付 90% 面试”的总结
Java 中:
栈管“方法和局部变量”,
堆管“对象和数组”,
方法区管“类和静态”,
引用在哪,对象永远在堆。

浙公网安备 33010602011771号