[转]谈谈Java中"=="与"equals()"

equals是Object超类中的一个方法,这个方法的实现就是通过==号实现的,==号比较的是两个对象的地址是否相同,在代码中体现出来就是比较两个对象引用中保存的地址是否相同,==能够判断的只是两个对象引用是不是指向同一个地址也就是同一个对象,所以它的相等判断是局限的:

A a1 = new A();A a2 = a1;这个时候a1 == a2是否为true?答案是yes,因为两个对象引用保存的是同一个对象的地址; A a1 = new A();A a2 = new A();这个时候a1 就不 == a2了,因为两个对象引用指向的是不同的对象. 正因为==号只能判断两个对象引用是否指向同一个对象,所以决不能用它比较两个普通对象是否相等,即使两个对象所有的实例域都相同,虽然这在现实中的语义是两个对象指的是同一个事物比如同一个人,但是因为在代码中它们分配在不同的地址,所以用==号判断它们是不相等的. 学过c#的人都知道,c#是可以用==号进行字符串相等判断的,那是c#对==进行运算符重载了的,java中没有运算符重载,哦,有一个,就是+号,能够用来拼接字符串,所以java不能用==号进行字符串相等判断.

对于字符串,有必要深究一下,是不是所有的字符串都不能用==号进行判断了,答案是no: 虚拟机将字符串常量是共享的,所以对于引用字符串常量的变量是可以用==号判断的,但是字符串的其他操作比如new String("HelloWorld") + substring replace等产生的新字符串不是共享的,所以后面这些方法产生的字符串不能用==号进行判断.给出下面一个例子: String hello = "hello';//hello是一个字符串常量的引用 if(hello == "hello")//true     ... if(hello.substring(0,3) == "hel")//false     ... 上面的例子中"hello" 和 "hel"都是字符串常量.

那么要按照现实世界的语义来比较两个对象是否相等,比如两个字符串含有的字符个数一样,对应索引上的字符一样也一样我们就认为它们相等,而不是仅仅判断内存地址来决定,该怎么办呢?解决方法就是重写equals方法,前面说过了Object超类中的equals方法就是用==实现的,所以假如一个类没有重写equals方法,那么当应用a1.equals(a2)时,跟用==号判断是一样的,所以要根据对象的实例域来判断两个对象是否相等的话一定要重写equals方法,eclipse有快速生成equals的捷径,你用到它的时候就知道了.

有了equals方法以后,我们再进行相等判断就不是根据对象的地址了,而是看你怎么实现这个equals方法,一般是根据对象的实例域来比较,比如姓名,身份证号,反正是一些特有或通用的属性,这个eclipse知道.

讲这么多只是告诉你==和equals进行相等测试时有哪些相似的和不同的地方,希望对你有所帮助.

posted @ 2014-01-13 10:29  Andy Zhai  阅读(327)  评论(0编辑  收藏  举报