JAVA内存机制

wjsq0705 2013-03-19 05:10:27
问个常见,但总有人纠结的问题。
String str1="abc";
String str2="abc";
System.out.println(str1==str2);//true
System.out.println(str1.equals(str2));//true
两个输出都是true.

第一个对比的是栈里面内容,实际上是一个“abc”,这点我可以想的通。
那我想知道equals这时对比的是堆里的还是栈里的,按理说这两个“abc”是创建的变量,都存在于栈中,并不存在于堆中,难道equals对比的是栈值?求解。求真正懂得人,不懂不要误解我。。。
...全文
187 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
jswatcher 2013-03-19
  • 打赏
  • 举报
回复
抱歉,我不太明白 这里中文IT用语的“堆”和“栈”指什么。用英文IT词,解释就是: 编译器把 常量 string literal "abc", 优化存贮到一个 string pool, 一般在 data memory 里; 变量 str1, str2 的string instance 是存储于 stack, 但是它的值的参照是 "abc" 的地址。 但是也有可能,有某个编译器(),为变量 str1, str2, 复制 "abc" 的值,把它放在stack 里。 Who knows!
jswatcher 2013-03-19
  • 打赏
  • 举报
回复
引用 1 楼 zoeg 的回复:
编译器优化的时候把str1和str2指向了同一个内存地址,但这不是强制要求的,也不被保证 equals是逐字取出比较,==比较的是内存地址
--------- 关于 为什么 "str1==str2 是 true": 1 楼 说的完全正确。 这和 API 完全没关系,是编译器的问题。完全同样的 API, 你也可能遇到一个特殊的编译器,编译得结果会造成 str1!=str2. 但是大多数编译器的结果,都将是 str1==str2, true!. 这是编译器,优化不同地方引用的常数 "abc"的存储,共用一个"abc"存储的结果。 但是,编译器是否优化常数存储,怎样优化,不是 Java 标准所关心的问题,所以Java 标准 也不保证 str1 和 str2 参照的是否是同一地址,也就是不保证 "str1==str2 必须是 true". 最后,关于 str1.equals(str2): 这是 J2SE API 定义的 String class 里 equals 函数的行为:对 String 的值中的 characters 进行 逐个比较。具体的,API 有叙述。
dracularking 2013-03-19
  • 打赏
  • 举报
回复
先看下介绍吧 Java Virtual Machine Stacks Each Java virtual machine thread has a private Java virtual machine stack, created at the same time as the thread. A Java virtual machine stack stores frames (§2.6). A Java virtual machine stack is analogous to the stack of a conventional language such as C: it holds local variables and partial results, and plays a part in method invocation and return. Because the Java virtual machine stack is never manipulated directly except to push and pop frames, frames may be heap allocated. The memory for a Java virtual machine stack does not need to be contiguous. 栈存储的只是本地变量和中间结果 ==比较的是是否同一个Object(对于引用型变量来说) equals本质上还是是否相同对象,只是相同对于不同具体对象来说意义有变化(通过覆盖),对于String来说内容相同即相同
龙四 2013-03-19
  • 打赏
  • 举报
回复
Java对象不会存在于栈里,即使JIT中经过逃逸分析实施栈上替换,那也不是完整对象
黑石课堂 2013-03-19
  • 打赏
  • 举报
回复
引用 4 楼 wjsq0705 的回复:
引用 2 楼 zhou9898 的回复:可以看看JAVASE API里面String有个缓冲池, 定义:当缓冲池中有这个值的时候直接返回引用。如果没有那么new一个。 此时可以知道str1==str2 此时的equals的是String这个方法重写过的。(还能明白?) 所以最后,equals比较的是值,两个值显然相等。 ==比较的是引用,显然str2就是st……
这个。你看看API吧,然后自己琢磨琢磨,既然你都问了这个问题了。说明你还是喜欢琢磨的。 很简单。StringAPI。。
wjsq0705 2013-03-19
  • 打赏
  • 举报
回复
引用 2 楼 zhou9898 的回复:
可以看看JAVASE API里面String有个缓冲池, 定义:当缓冲池中有这个值的时候直接返回引用。如果没有那么new一个。 此时可以知道str1==str2 此时的equals的是String这个方法重写过的。(还能明白?) 所以最后,equals比较的是值,两个值显然相等。 ==比较的是引用,显然str2就是str1的引用,此时相等。 最后和堆栈……
额。。能请你说说这个缓冲池吗?他既不属于栈也不属于堆吗?说的不大理解。“定义:当缓冲池中有这个值的时候直接返回引用。如果没有那么new一个。”你的这个话是针对什么说的?举个例子
wjsq0705 2013-03-19
  • 打赏
  • 举报
回复
引用 1 楼 zoeg 的回复:
编译器优化的时候把str1和str2指向了同一个内存地址,但这不是强制要求的,也不被保证 equals是逐字取出比较,==比较的是内存地址
你的意思是,equals比较时如果发现引用地址并没指向堆的任何内容。就会比较栈中内存的值?
黑石课堂 2013-03-19
  • 打赏
  • 举报
回复
可以看看JAVASE API里面String有个缓冲池, 定义:当缓冲池中有这个值的时候直接返回引用。如果没有那么new一个。 此时可以知道str1==str2 此时的equals的是String这个方法重写过的。(还能明白?) 所以最后,equals比较的是值,两个值显然相等。 ==比较的是引用,显然str2就是str1的引用,此时相等。 最后和堆栈没关系的。 不过,栈中放的是:引用和基本类型的值 堆中放的是:引用类型的值,也就是对象本事了。。这个可以谷歌。。
zoeg 2013-03-19
  • 打赏
  • 举报
回复
编译器优化的时候把str1和str2指向了同一个内存地址,但这不是强制要求的,也不被保证 equals是逐字取出比较,==比较的是内存地址

51,409

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧