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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 杨立 中级黑马   /  2012-11-15 14:15  /  1946 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 杨立 于 2012-11-15 17:30 编辑
  1. String str1 = "LUCY";
  2. String str2 = "LUCY";
  3. System.out.println(str1.equals(str2));
  4. System.out.println(str1 == str2);这里输出都是true,他们不是一个相同引用怎么是true;
  5. public class Student {
  6.         private Integer id;
  7.         private String name;
  8.         private int age;
  9.         private String adder;

  10.         Student(String name, int age) {
  11.         }
  12. }
  13. Student a = new Student("LUCY", 20);
  14. Student b = new Student("LUCY", 20);
  15. System.out.println(a == b);
  16. System.out.println(a.equals(b));这里输出都是false,两个参数的值是一样的equals()比较为什么是false
复制代码

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 赞一个!

查看全部评分

8 个回复

倒序浏览
第一个。为什么str1和str2 比较都能得到 true。
首先你要了解的是String的不可变。 "LUCY" 这个字符串在内存里创建后。不再更改会被更改,就相当于她被 final了。
于是当你把"LUCY"给两个String时 ,你以为是在内存创建了两个区域来存"LUCY" ,其实他们持有的都只是"LUCY" 的引用。

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
第二个。equals()为什么又不相等了。

equals()是object 中方法。equals()描述中有讲到 hashcode。

相等对象必须具有相等的哈希码
回复 使用道具 举报
解决此题首先要明确“==”和equals的区别:
(1)==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符
如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(堆内存),变量也占用一块内存,例如Objet obj = new Object();变量obj是一个内存,new Object()是另一个内存,
此时,变量
obj所对应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。
(2)equals方法是用于比较两个独立对象的内容是否相同。
懂得两者的区别后,在需要了解String类和我们自定义类中的equals方法了
对于String,它复写了Object中的equals方法,看它的源码:
public boolean equals(Object anObject) {
if (this == anObject) {
     return true;
}
if (anObject instanceof String) {
     String anotherString = (String)anObject;
     int n = count;
     if (n == anotherString.count) {
  char v1[] = value;
  char v2[] = anotherString.value;
  int i = offset;
  int j = anotherString.offset;
  while (n-- != 0) {
      if (v1[i++] != v2[j++])
   return false;
  }
  return true;
     }
}
return false;
    }
内存中如图:

str1和str2指向的是同一个对象,所以str1.equals(str2)和str1==str2都返回真
但是对于我们自定义的类Student来说,它没有复写Object中的equals方法,
它默认的equals方法(从Object 类继承的)就是使用==操作符

所以两者都为false,希望是你想要的答案

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
  • String str1 = "LUCY";
  • String str2 = "LUCY";
  • System.out.println(str1.equals(str2));
  • System.out.println(str1 == str2);这里输出都是true,他们不是一个相同引用怎么是true;
先回答第一个问题,如下图

str1,str2是在栈内存,都指向堆内存的"LUCY"。str1.equals(str2))是比较的内容,内容都是"LUCY",所以true;
str1 == str2则是比较指向的堆内存地址空间,显然也是相同,所以true.


评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 陈龙 于 2012-11-15 15:14 编辑

public class Student {

        private Integer id;

        private String name;

        private int age;

        private String adder;


        Student(String name, int age) {

        }

}

Student a = new Student("LUCY", 20);

Student b = new Student("LUCY", 20);

System.out.println(a == b);

System.out.println(a.equals(b));这里输出都是false,两个参数的值是一样的equals()比较为什么是false
首先,new出来的对象,都是保存在堆内存中,new一次就会分配一个空间,如下图



a == b比较指向的堆内存地址,这个是不同的,所以false;
a.equals(b),因为比较的对象是自定义类型Student,equal默认的做法不是去比较内容,而是用"=="比较,即在这个例子,a.equals(b)就相当于a == b,所以false

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 罗会涛 于 2012-11-15 16:26 编辑

有两个问题明白就可以了,
一是关于字符串常量极其存放位置.
直接把一个字符串对象赋给一个字符串引用.如:String str1 = "LUCY";与new一个字符串对象是不一样的.如:String str1 = new String("LUCY");虽然两种都是对象但在内存中存放的位置不一样.前一种是个常量在共享去里面,当你再次把这个常量对象赋给另外一个String引用如:String str2 = "LUCY";是不会在内存再开辟空间存储这个LUCY的,他会发现常量池里有了一个,就直接让str2也指向这个LUCY,那么这个时候两个字符串引用全都指向LUCY.你用"=="他们肯定是一样的.
第二个问题是"=="与"equals"的区别.
==是比较地址值,他是系统支持的表达形式,你只要写==就表示比较地址值.而equals只不过是一个方法,具体相不相等你得看方法的内容,它根据什么来判断相等(他返回的是个boolean值).但是要注意的是object类中的equals方法是返回的两个对象的"==".任何对象的基类都是object,所以任何对象的默认equals方法都是返回==值,也就是说你要是重写equals就返回你指定的,否则就按照你父类(即object)equals方法来返回(就是按==返回).
String是继承object的但是他重写了equals(可以去看jdk),他是按字符串内容是否相同来返回的.你的Student也是继承Object的,但是你没有重写equals,那么当然继承父类方法按"=="返回.你学生中的内容相同与你equals返回值没有一点联系,你要是愿意,你Student中重写equals方法直接让他返回false,就算你学生中的内容在怎么一致,你equals的结果永远是false.记住equals只是个方法,虽然它的英文释义为"相等".

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
JAVA不能重载运算符吗?
回复 使用道具 举报
杨立 中级黑马 2012-11-15 17:13:54
9#
受教了,多谢大家。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马