日期:2014-05-20  浏览次数:20706 次

JAVA内存机制
问个常见,但总有人纠结的问题。
String str1="abc";
String str2="abc";
System.out.println(str1==str2);//true
System.out.println(str1.equals(str2));//true
两个输出都是true.

第一个对比的是栈里面内容,实际上是一个“abc”,这点我可以想的通。
那我想知道equals这时对比的是堆里的还是栈里的,按理说这两个“abc”是创建的变量,都存在于栈中,并不存在于堆中,难道equals对比的是栈值?求解。求真正懂得人,不懂不要误解我。。。
equals java

------解决方案--------------------
编译器优化的时候把str1和str2指向了同一个内存地址,但这不是强制要求的,也不被保证
equals是逐字取出比较,==比较的是内存地址
------解决方案--------------------
可以看看JAVASE API里面String有个缓冲池,
定义:当缓冲池中有这个值的时候直接返回引用。如果没有那么new一个。
此时可以知道str1==str2
此时的equals的是String这个方法重写过的。(还能明白?)

所以最后,equals比较的是值,两个值显然相等。
==比较的是引用,显然str2就是str1的引用,此时相等。

最后和堆栈没关系的。

不过,栈中放的是:引用和基本类型的值
堆中放的是:引用类型的值,也就是对象本事了。。这个可以谷歌。。
------解决方案--------------------
Java对象不会存在于栈里,即使JIT中经过逃逸分析实施栈上替换,那也不是完整对象
------解决方案--------------------
先看下介绍吧

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来说内容相同即相同