Java String 对象创建与内存分配笔记

AI-摘要
LNotes-AI GPT
AI初始化中...
介绍自己 🙈
生成本文简介 👋
推荐相关文章 📖
前往主页 🏠
前往爱发电购买
Java String 对象创建与内存分配笔记
LiuxzJava String 对象创建与内存分配笔记
一、核心概念:字符串常量池(Constant Pool)
- 作用:存储字符串常量(如
"abc"),实现对象共享,避免重复创建相同内容的字符串,节省内存 - 加载时机:类加载时,字符串常量会被自动读取并放入常量池
- 核心规则:常量池中相同内容的字符串仅存在 1 个,后续使用相同常量时直接复用,不新建
二、String 对象创建的两种方式及内存分析
方式 1:直接赋值(String s = "abc")
- 内存过程:
- 检查常量池:若不存在
"abc",则在常量池创建 1 个"abc"对象 - 若常量池已存在
"abc",则直接让变量s指向常量池中的该对象
- 检查常量池:若不存在
- 对象数量:仅在首次赋值时创建 1 个(常量池),后续赋值不新建对象
方式 2:new关键字创建(String s = new String("abc"))
- 内存过程(分首次和后续):
- 首次执行(常量池无
"abc"):- 先在常量池创建 1 个
"abc"对象(类加载时或首次遇到常量时) - 再在堆内存创建 1 个新的
String对象(内容与常量池一致) - 变量
s最终指向堆中的对象 - 对象总数:2 个(常量池 1 个 + 堆 1 个)
- 先在常量池创建 1 个
- 后续执行(常量池已有
"abc"):- 不再创建常量池对象,仅在堆内存新建 1 个
String对象 - 变量
s指向堆中的新对象 - 对象总数:1 个(仅堆中新建)
- 不再创建常量池对象,仅在堆内存新建 1 个
- 首次执行(常量池无
三、典型案例分析
案例 1:两次new创建相同常量
java
1 | String a3 = new String("xyz"); // 2个对象(常量池"xyz" + 堆1个) |
- 总对象数:3 个(常量池 1 个 + 堆 2 个)
案例 2:字符串拼接(new String("hello") + new String("world"))
- 内存过程(共创建 6 个对象):
- 常量池:创建
"hello"和"world"(2 个) - 堆内存:
new String("hello")→ 堆 1 个new String("world")→ 堆 1 个- 底层隐式创建
StringBuilder对象(用于拼接)→ 堆 1 个 StringBuilder.toString()→ 生成新的"helloworld"对象(堆 1 个,常量池无此对象)
- 常量池:创建
- 关键注意:拼接结果
"helloworld"仅在堆中存在,不会放入常量池
四、核心总结
| 创建方式 | 常量池对象 | 堆对象 | 总对象数(首次 / 后续) |
|---|---|---|---|
直接赋值 String s = "a" |
1 个(复用) | 0 个 | 1 个 / 0 个 |
new String("a") |
1 个(复用) | 1 个(每次新) | 2 个 / 1 个 |
拼接 new String("a")+new String("b") |
2 个(”a”/“b”) | 4 个(2 个 String + 1 个 StringBuilder + 1 个拼接结果) | 6 个 |
- 核心区别:
==比较对象地址(常量池 vs 堆不同则为 false),equals()比较内容(相同则为 true) - 常量池仅存储编译期确定的字符串常量,运行时拼接结果(如
new拼接)不会进入常量池
评论
匿名评论隐私政策
✅ 你无需删除空行,直接评论以获取最佳展示效果




