- 基本类型、引用存于内存的栈中。
对象存于内存的堆中。 - 基本类型、引用的比较用 ==
对象间的比较用 equals
下面就以一个实例来分析equals和==的异同,先请看一段程序和它的运行结果:
- 结果中a=b,很容易理解,数据基本类型的a、b相等。
- 结果中未出现c=d,这是因为c,d为引用类型,且都指向了由new创建的两个对象(注意,这是两个不同的对象),而c,d存的是这两个不同的对象的地址,所以c不等于d。
- 结果中出现c equals d,这是因为equals比的是c和d这两个引用所String的内容。
注意:equals()是Object类的一个方法,所以每个对象都会有equals()方法,而默认的equals是比较两个对象的内存地址。而String覆盖了这个方法,用于比较两个字符串的内容是否相等。 - 结果中出现e=f,而e,f是两个引用,这说明指向了同一块内存(即"ccc"所在的内存),即e和f存的内存地址值相等,故而它们相等。
- e equals f 也比较好理解,同一块内存的值当然相等了。
- c,d,e,f 的hashCode值都是98307,而Object默认是用内存地址作为hashCode的值(注:hash code是一种“将对象内的某些信息转换为几乎独一无二”的int,用以代表这个对象),而c,d,e,f 的内存地址肯定不是一样的啊,查了java API 后知道,String覆写了hashCode()方法,用下面的公式来计算hashcode
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
其中s[i]代表字符串中的第i个字符,n代表字符串的长度。
这就解释了为什么c,d,e,f 的hashcode为什么相等。
所以两个对象的hashcode相等,则两个对象可能相同。 - 当想比较两个自己编写的类的对象是否逻辑上相等,而不仅仅是地址相同时,请覆写equals()方法,并在其中比较两个对象的成员变量,方法是没法比较的啊。