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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 微凉的暮色   /  2015-6-11 23:51  /  14680 人查看  /  72 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

好好理解下面的代码,体会体会
String s1 = new String("hello");
                    String s2 = new String("hello");
                    System.out.println(s1==s2);
                    System.out.println(s1.equals(s2));

                    String s3 = new String("hello");
                    String s4 = "hello";
                    System.out.println(s3==s4);
                    System.out.println(s3.equals(s4));

                    String s5 = "hello";
                    String s6 = "hello";
                    System.out.println(s5==s6);
                    System.out.println(s5.equals(s6));
回复 使用道具 举报
==比较的是内存地址值;
equals比较的是内存中的具体内容;
回复 使用道具 举报
wdd 中级黑马 2015-6-15 14:31:29
23#
没看懂什么意思,来围观答案
回复 使用道具 举报
==比较最后的值  equlse比较的是地址  重写equlse就是比较最后的值
回复 使用道具 举报
任何对象都会有equals方法,因为是从object类继承而来的。
你可以默认为objict类当中的equals方法就是==。
有些情况下自己写的类是需要重写equals方法的,修改后的equals方法会去比较双方的地址和真实的值。
所以从object类当中继承来的equals方法与==结果相同,自己重写的equals方法面对两个值相同但是地址不同的对象时也可以返回false。

不知道说的对不对,以上是我个人学习的结果。

点评

简单理解这样很对,不过很多时候== equals 都要用到,==优先于equals作比较,原则是先引用(地址),后具体(内部对象)  发表于 2015-6-17 16:30
回复 使用道具 举报
ice24 中级黑马 2015-6-15 23:44:34
26#
equals属于Object的方法 ,比较的是引用类型的地址值,而String重写了equals方法,比较内容是否相等 ,直接打印数组,出现的就是地址值。你可以查看下源码Object的equals方法。谢谢。
回复 使用道具 举报
equal是方法,而==是条件表达式
回复 使用道具 举报
(转)==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。
如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(堆内存),变量也占用一块内存,例如Objet obj = new Object();变量obj是一个内存,new Object()是另一个内存,此时,变量obj所对应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。
equals方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。例如,对于下面的代码:
String a =new String("foo");
String b=new String("foo");
两条new语句创建了两个对象,然后用a,b这两个变量分别指向了其中一个对象,这是两个不同的对象,它们的首地址是不同的,即a和b中存储的数值是不相同的,所以,表达式a==b将返回false,而这两个对象中的内容是相同的,所以,表达式a.equals(b)将返回true。
在实际开发中,我们经常要比较传递进行来的字符串内容是否等,例如,String input = …;input.equals(“quit”),许多人稍不注意就使用==进行比较了,这是错误的,随便从网上找几个项目实战的教学视频看看,里面就有大量这样的错误。记住,字符串的比较基本上都是使用equals方法。
如果一个类没有自己定义equals方法,那么它将继承Object类的equals方法,Object类的equals方法的实现代码如下:
boolean equals(Object o){
return this==o;
}

这说明,如果一个类没有自己定义equals方法,它默认的equals方法(从Object类继承的)就是使用==操作符,也是在比较两个变量指向的对象是否是同一对象,这时候使用equals和使用==会得到同样的结果,如果比较的是两个独立的对象则总返回false。如果你编写的类希望能够比较该类创建的两个实例对象的内容是否相同,那么你必须覆盖equals方法,由你自己写代码来决定在什么情况即可认为两个对象的内容是相同的。
回复 使用道具 举报
==:在比较引用型变量时,比较的是内存地址值。equals:是Object下的方法,当没有重写时,比较的也是地址.
具体到String类下,String他写了equals方法,比较的具体的字符串是否相同。
代码体现:
String s1 = new String("abc");//创建对象s1
String s2 = new String("abc"); //创建对象s2
System.out.println(s1 = = s2);//这时输出的结果为false,通过==比较的是两个对象的内存地址值。
System.out.println(s1.equals(s2));//结果为true,比较的是具体的两个字符串。

注意:
当没有创建对象直接指向字符串常量时,==由于指向的是常量池地址,所以他们是相等的。
String s3 = "abc";
String s4 = "abc";
System.out.ptintln(s3 == s4 ); \\结果为true,由于字符串时常量,这时s3、s4同时指向了字符串常量池中的"abc"常量,所以地址值相同.


hashCode()方法,返回的是一个虚拟的内存地址值,可以通过比较哈希值来判断是否是同一个对象。





回复 使用道具 举报
直接跟你说吧,equals是Object类下的子类,如果Equals被重写了就是比较内容,如果没被重写就是比较地址值,==号一般是比较内容,但是这个例子你需要好好理解
String s1="你好";
String s2=“吗”;
Strings3=“你好吗”;
System.out.println(s3==“|你好”+"吗");结果是true
System.out.println(s3==s1+s2)结果是false
原因是,前者在编译的时候结果已经出来了
后者判断的话先要在常量池开辟空间,然后赋值到堆内存,所以结果为false
回复 使用道具 举报
贴个源码加注释
/**这是String的成员equals方法的定义*/
public boolean equals(Object anObject) {
    //首先判断两个String引用是不是同一个对象
//this代表是调用对象的引用(地址),anObject是被比较对象的引用(地址)
//如果两个地址都相同,即是同一个对象,不用比较。当然返回true
        if (this == anObject) {
            return true;
        }
//如果对象是String类型的一个实例,则执行if内的操作
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
//如果两个字符串的长度不相等,不再比较,返回false
//相等就进入if继续判断
            if (n == anotherString.value.length) {
//把String类型的字符串,转换成底层的char类型的数组来判断
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
               //对两个string类型的转化后的char类型数组中的每个元素逐个比较,都相等即返回true。如遇到不相等的元素就返回fals
                while (n-- != 0) {
                    if (v1 != v2)
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

总之,equals比较的是String中的每个字符的ascii码值是否相等,只要有不相等的就返回false。以上是个人见解,可能有描述不太得当的地方,仅为了好理解,纯手打。

评分

参与人数 1黑马币 +1 收起 理由
微凉的暮色 + 1 赞一个!

查看全部评分

回复 使用道具 举报
微凉的暮色 发表于 2015-6-13 09:58
差不多,输出的是他们的引用值

你可以看下底层代码,==是比的一次引用值,equals比的是对象里的内容

评分

参与人数 1黑马币 +1 收起 理由
微凉的暮色 + 1 其实我很想把这个输出

查看全部评分

回复 使用道具 举报
== 和 Equals 的区别
  1. == 是一个运算符。
  2.Equals则是string对象的方法,可以.(点)出来。
  
  我们比较无非就是这两种 1、基本数据类型比较 2、引用对象比较
  1、基本数据类型比较
  ==和Equals都比较两个值是否相等。相等为true 否则为false;
  
  2、引用对象比较
  ==和Equals都是比较栈内存中的地址是否相等 。相等为true 否则为false;
  
  需注意几点:
  1、string是一个特殊的引用类型。对于两个字符串的比较,不管是 == 和 Equals 这两者比较的都是字符串是否相同;
  2、当你创建两个string对象时,内存中的地址是不相同的,你可以赋相同的值。
  所以字符串的内容相同。引用地址不一定相同,(相同内容的对象地址不一定相同),但反过来却是肯定的;
  3、基本数据类型比较(string 除外) == 和 Equals 两者都是比较值;
回复 使用道具 举报
楼上的都答非所问。
0、HashCode不是内存地址,是根据排列算出来的一个值,hashCode是指对象的散列码,具体值是由对象的hashCode()方法返回的值,但绝不是内存地址,你甚至可以重写该方法让每个对象的hashCode都一样。
1、
  1. String str =new String("XYZ");
  2. str.getBytes();
复制代码

一个对象用getBytes()多运行几遍发现得到的值也会不同。
getBytes()得到的是一个byte的数组对吧。你要看得到的byte应该遍历打印这个byte数组里的元素,而不是直接打印byte对象。
  1.                 byte[] by = str.getBytes();
  2.                  for(int i=0;i<by.length;i++)  {
  3.                      System.out.println(by[i]);
  4.                  }
复制代码

这样就相同了
2、如果一个值是引用类型的,那么它的存储空间将从堆中分配.由于引用值的大小会改变,所以不能把它放在栈中,
则放入堆中,而堆中的内存地址是变化的无法得到。
希望解决你的问题。
回复 使用道具 举报
825176857 发表于 2015-6-17 16:00
楼上的都答非所问。
0、HashCode不是内存地址,是根据排列算出来的一个值,hashCode是指对象的散列码,具体 ...

:o
能把第二点仔细说下么?
回复 使用道具 举报
微凉的暮色 发表于 2015-6-13 09:58
差不多,输出的是他们的引用值

应该得重写toString才能看到他们的引用值,不重写看到的只能是他们的内容,或许你可以用其他类型的试试,不用String类型
回复 使用道具 举报
逝....曾经 发表于 2015-6-17 17:26
应该得重写toString才能看到他们的引用值,不重写看到的只能是他们的内容,或许你可以用其他类型的试试, ...

重写,我只能返回hashCode(), 要输出两边的比较内容,API里没找到方法
而且都说,java 不能返回地址值
正在等待楼上的楼上 详解这个地址的问题
回复 使用道具 举报
微凉的暮色 发表于 2015-6-17 17:49
重写,我只能返回hashCode(), 要输出两边的比较内容,API里没找到方法
而且都说,java 不能返回地址值
正 ...

你试试这个;自己定义一个类,然后再创建实例。多创建几个实例再比较一下
试试
回复 使用道具 举报
微凉的暮色 发表于 2015-6-17 16:35
能把第二点仔细说下么?

String str=“XYZ”;
         str=“str”;
变量str是在栈内存中的 他开始存的是堆内存中“XYZ”的字符串的内存地址变为“str”字符串的内存地址。至于“XYZ” “str”的内存地址是多少,没办法知道的。因为在程序运行过程中,每创建一个对象都会被分配一定的内存用以存储对象数据。如果只是不停的分配内存,那么程序迟早面临内存不足的问题。所以在有一个内存回收机制来释放过期对象的内存,以保证内存能够被重复利用。
回复 使用道具 举报
==比较两个变量引用的对象是否相等,即变量指向的内存地址是否相等。
equals的比较逻辑每个类都不一样,String的equals是遍历String 的每一个字符是否相等。
objetct 的 hashcode 返回该对象的内存地址,
Object:
public native int hashCode(); 所以是用jni获得滴
public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
        Object o1 = new Object();
                Object o2 = new Object();
                System.out.println(o1);
                System.out.println(o2);
java.lang.Object@15db9742
java.lang.Object@6d06d69c
地址就是那串数字
String 重写了hashcode,所以拿不到地址。
我没遇到过获得对象内存地址的API。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马