A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 高欢欢 中级黑马   /  2012-7-14 19:33  /  2204 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 高欢欢 于 2012-7-18 07:32 编辑

基本数据类型比较只能用==运算符比较是否相等,而引用数据类型==比较的是两个对象的内存地址是否相等,通过覆盖equals的方式,equals可以比较啊两个对象的内容是否相等。
我想问一下,假设有两个对象s1和s2,如果s1==s2结果是true,那么s1.equals(s2)一定为true,这句话对吗?为什么?

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

9 个回复

倒序浏览
本帖最后由 黑马-王言龙 于 2012-7-14 19:39 编辑

是正确的

两个对象引用==为true,说明指向了同一个内存中的对象,那equals比较也一定为true
回复 使用道具 举报
  1. public boolean equals(Object anObject) {
  2. //观察下面三行代码,首先判断两个引用是否指向同一对象
  3.         if (this == anObject) {
  4.             return true;
  5.         }
  6. //其次才是比较两个引用所指向的对象的内容是否相等
  7.         if (anObject instanceof String) {
  8.             String anotherString = (String)anObject;
  9.             int n = count;
  10.             if (n == anotherString.count) {
  11.                 char v1[] = value;
  12.                 char v2[] = anotherString.value;
  13.                 int i = offset;
  14.                 int j = anotherString.offset;
  15.                 while (n-- != 0) {
  16.                     if (v1[i++] != v2[j++])
  17.                         return false;
  18.                 }
  19.                 return true;
  20.             }
  21.         }
  22.         return false;
  23.     }
复制代码
以上为String类的equals方法底层实现;
通过观察可以发现无论是系统自己底层实现的equals方法还是自己重写的,一般都是先判断两个引用是否指向同一个对象,如果是,则返回真。
试想,两个引用指向的是同一对象,还有什么是不相等的呢?
因此,如果s1==s2结果是true,那么s1.equals(s2)一定为true,这句话是正确的。

回复 使用道具 举报
本帖最后由 黑马刘涛 于 2012-7-14 19:57 编辑

问题:假设有两个对象s1和s2,如果s1==s2结果是true,那么s1.equals(s2)一定为true?
每个类都是使用Object作为超类的,所有对象(包括数组)也实现这个类方法。
对于Object类的equals方法如下:
public boolean equals(Object obj) {   
    return (this == obj);   
}  
即是说关于一个普通类,没有作出覆盖equals方法时,改类的比较"=="与equals操作的结果是相同的。
然而当你复写了equals方法,而对象都是new出来的(String类比较特殊除外,比如String str = "abc";如果堆中有一个"abc"常量,就不会new,str直接引用abc的地址),你new了两个对象,就在堆上创建了两个地址不同的对象,理论上s1==s2结果为false,不可能为true。所以你这个问题的前提条件有点问题。
你对自定义类复写了自己应用需要(比如字符串equals方法比较的就是两个串的内容是否相同)的equals方法后,比较就可能不是地址是否相同,而是对象的内容。

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

回复 使用道具 举报
基本数据类型比较只能用==运算符比较是否相等,而引用数据类型==比较的是两个对象的内存地址是否相等,通过覆盖equals的方式,equals可以比较啊两个对象的内容是否相等。
我想问一下,假设有两个对象s1和s2,首先这句话,我觉得楼主问的就有问题呀,如果是两个对象,那就两块内存,而==比较的就是内存是否相同,所以又何来s1==s2结果是true之说呢?如果是两个对象,这个结果一定false。而equals比较的是两个对象的内容是否相同,
如果S s1=new s1();
S s2=new s2();
那这时s1==s2 为false,s1.equals(s2)为true

而当S s1=new s1();
S s2=s1
此时s1==s2 定为true,s1.equals(s2)也为为true

这种情况就相当于s1这个对象有两个名字,同时指向的是一个人,你说他们的内存地址能不相同吗,当然内容也相同了,所以引用数据类型只要s1==s2结果是true,那么s1.equals(s2)一定为true,这句话肯定对呀
如果s1==s2结果是true,那么s1.equals(s2)一定为true,这句话对吗?为什么?

评分

参与人数 1技术分 +1 收起 理由
刘笑 + 1 "假设有两个对象s1和s2,首先这句话,我觉.

查看全部评分

回复 使用道具 举报
基本数据类型比较只能用==运算符比较是否相等,而引用数据类型==比较的是两个对象的内存地址是否相等,通过覆盖equals的方式,equals可以比较啊两个对象的内容是否相等。
我想问一下,[color=Red]假设有两个对象s1和s2,首先这句话,我觉得楼主问的就有问题呀,如果是两个对象,那就两块内存,而==比较的就是内存是否相同,所以又何
回复 使用道具 举报
位雪 中级黑马 2012-7-14 20:04:47
7#

感觉你的问题前提条件有点问题,通过两个例子分析一下
例一
public class EqualsMethod {
public static void main(String[] args) {
String str =“wxy//在栈内存中定义一个str1变量,然后在常量池中创建"wxy,然后将地址传给str1str1指向了"wxy"
String str2=new Stringwxy);//在栈内存中定义一个str2变量,然后在堆内存中创建String对象,然后再创建一个wxy,并将其地址传给str2
System.out.println(str1==str2)//这里比较的是地址,一个是常量池的,一个是堆内存的,肯定不一样啊,所以返回false
System.out.println(str1.equals(str2));//这里比较的是内容,所以返回的是true
}
}
例二
class Value
{
int n;
}
public class EqualsMethod1 {
public static void main(String[] args) {
Value v1 = new Value();
Value v2 = new Value();
v1.i = v2.i = 100;
System.out.println(n1.equals(n2));//这里的equals()用的是Object类中的,没有经过复写,在这里和”==“功能相同,比较的是地址,因为这里是new了两个对象,地址
} //肯定不同,所以返回的是false
}


回复 使用道具 举报
因为==为true说明他们的是一个内存,他们都是同一个内存了,一个位置只能有一个值,所以他们的值是一个所以为true
回复 使用道具 举报
如果s1==s2结果是true,那么s1.equals(s2)一定为true,这句话正确。
但是反过来说就是错的。
即:如果s1.equals(s2)为true,则s1==s2一定为true。这句是错误的。
回复 使用道具 举报
"=="比较的是内存地址,"equals"比较的是值。
当S1==S2为true时内存地址相同,S1和S2引用相同的内存空间,
所以S1的值发生改变时S2的值也随之发生改变。
所以s1.equals(s2)一定为true
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马