从java equals和==说起
程序运行时,对象时怎么进行放置安排的?特别内存是怎么分配的?对于这方面的了解对我们理解程序的运行有很大的帮助。有五个地方可以存储数据:
1》存储器。这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部。但是寄存器的数量极其有限,所以寄存器根据需求进行分配。
2》堆栈。堆栈简称栈(stack),位于通用RAM,但通过堆栈指针可以从处理器那里获得直接支持。堆栈指针若向下移动,则分配新的内存;若向上移动,则释放那些内存。这是一种快速有效的分配存储方式,仅次于寄存器。java的对象引用就存储于堆栈中。
3》堆(heap)。一种通用的内存池(也存在于RMA中),用于存放java对象。堆不同于栈的好处是:编译器不需要知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。当需要一个对象时,只需要new写一行简单的代码,当执行这行代码时,会自动在堆里进行存储分配。用堆进行存储分配和清理可能比用栈进行存储分配需要更多的时间。
4》常量存储。常量值通常直接存放在程序代码内部,这样做是安全的,因为他们永远不会被改变。
5》非RMA存储。如果数据完全存活于程序之外,那么它可能不受程序任何控制,在程序没有执行时也可以存在。其中两个基本的例子是流对象和持久对象。在流对象中,兑现转化为字节流,通常被发送给另一台机器。在“持久化对象”中,对象被存放于磁盘上,因此,即使终止程序,它们人可以保持自己的状态。这种存储方式的技巧在于:把对象转化成可以存放在其他媒介上的事物,在需要时,可以回复成常规的,基于RMA的对象。java提供了对轻量级持久化的支持,而诸如jdbc和hibernate这样的机制提供了更加复杂的对在数据库中存储和读取对象信息的支持。
以上几个概念主要摘自《Thinking In Java》,个人觉得对于上述几个概念的理解可以帮助我们更好的区分equals和==,下面说说两者的关系:
==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用类型的数据或两个引用变量是否相等,只能用==操作符。
如果一个变量指向的数据是对象类型的,那么这时涉及了两块内存,对象本身占用一块内存(堆内存),变量本身(这里即对象的引用)也占用一块内存(栈内存),例如Object obj = new Object();变量obj时一块内存,new Object()是一个内存,此时,变量所对应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型变量,如果要比较两个变量是够指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候需要用==操作符进行比较。
equals方法适用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象时独立的。
简单的说就是:
==操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。
equals操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。
==比较的是2个对象的地址,而equals比较的是2个对象的内容。
下面看几个例子:
至于很多地方提到过的hashcode的概念,个人觉得比较难于理解,在这里就先不予讨论了。等自己真正理解这一块的时候再做比较。百度文库中有篇文中说得比较全面,贴出链接以供参考http://wenku.baidu.com/view/2d25e10d4a7302768e9939d7.html