黑马程序员技术交流社区

标题: JAVA中==和equals问题 [打印本页]

作者: 深圳在漂移    时间: 2013-7-19 14:16
标题: JAVA中==和equals问题
请问==和equals之间的区别和具体怎么应用,请举例说明,谢谢。
作者: 王靖远    时间: 2013-7-19 14:28
==是比较地址。equals是方法。可以自定义内容。
作者: yinjiek    时间: 2013-7-19 14:33
                String s1="123";
                String s2="123";
                String s3=new String("123");
               
                System.out.println(s1== s2);
                System.out.println(s1.equals(s2));
                System.out.println(s3==s1);
                System.out.println(s3.equals(s1));
s1==s2比较是两个地址相同;s1,s2都指向同一个对象;
s1.equals(s2)比较的是两个对象的值相同;是两个对象;
作者: 宋智超    时间: 2013-7-19 14:33
1,区别:==既可以比较基本数据类型,也可以比较引用数据类型,equals只能比较引用数据类型
2,在Object这个equals方法比较对象的地址值,依赖与==符号去比较,如果你想要建立自己的比较方式,得对Object这个
类中的方法进行重写
3,==号是个符号,equals是个方法,因为是方法就可以按照我们自己的意愿去比较
作者: yinjiek    时间: 2013-7-19 14:36
最后一行写错了是这个:s3.equals(s1)比较的是两个对象的值相同;是两个对象;
作者: Rainbow    时间: 2013-7-19 14:37
"=="对于基本类型来说比较的是左右两边的值是否相等。对于引用类型来说,比较的是左右两边的引用是否指向同一个对象,也可以说指向同一个地址。
"equals"String 类型比较的时候用equals方法是比较字符串的内容是否相等。
作者: xscn    时间: 2013-7-19 14:48
==可用于基本类型和引用类型:
当用于基本类型时候,是比较值是否相同;
当用于引用类型的时候,是比较引用型变量在堆中存储的地址是否相同,即栈中的内容是否相同。

equals比较的是两个对象堆中的内容是否相同。

比如
String str1  =new String("")
String str2  =new String("")
str1.equals(str2)的值为true,但是str1==str2的值为false,二者内容是相等的,但是内存中的位置地址值是不同的

作者: wedge    时间: 2013-7-19 15:21
equals和 == 比较的都是地址值是否相等
但是在某些类中,equals被重写了,重写后具体比较什么就得看它重写的内容。
例如:String类中equals的比较,其实就是重写了equals方法,比较的是内容是否相等。

作者: jialihong    时间: 2013-7-19 16:44
==比较的是地址,equals比较的是内容
作者: 张先庆    时间: 2013-7-19 22:40
       ①==和equals的实质。

       在JAVA中利用"=="比较变量时,系统使用变量在"栈"中所存的值作为比较的依据。

       基本数据类型在"栈"中存的是其内容值,而对象类型在"栈"中存的是地址,这些地址指向"堆"中的对象。

       java.lang包中的Object类有public boolean equals(Object obj)方法,它比较两个对象是否相等。

       其它对象的equals方法仅当被比较的两个引用指向的对象内容相同时,对象的equals()方法返回true。

       总之,"=="和"!="比较的是地址.也可认为"=="和"!="比较的是对象句柄;而equals()比较的是对象内容.或者说,,"=="和"!="比较的是"栈"中的内容,而equals()比较的是"堆"中的内容.

       ②==操作符。专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相当,只能用==操作符。

      Java的基本数据类型为(char,byte,short,int,long,float,double,boolean)。

      如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(对内存),变量本身也占用一块内存,例如Object obj = new Object()变量obj是一个内存,new Object()是一个内存,此时,变量所对应的内存中存储的数据就是对象占用的那块内存的首地址。对于指向对象内存的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。

           equals方法。用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。例如,对于下面的代码:

String a=new String("foo");

String b=new String("foo");

两条new语句创建了两个对象,然后用a,b这两个变量分别指向了其中一个对象,这是两个不同的对象,他们的首地址是不同的,即a和b中存储的数值是不相同的,所以,表达式a==b即返回false,而这两个对象中内容是相同的,所以,表达式a.equals(b)将返回true。

       在实际开发中,我们经常要比较传递进行来的字符串内容是否相等,许多人稍不注意就使用==进行比较了,这是错误的,有大量这样的错误。记住,字符串的比较基本都是使用equals方法。

       如果一个类没有定义equals方法。它将继承Object类的equals方法,Object类的equals方法的实现代码如下:

boolean equals(Object o){

return this==o;

}

这说明,如果一个类没有自己定义equals方法,它默认的equals方法(从Object类继承的)就是使用==操作符,也是比较两个变量指向的对象是否是同一个对象,这时候使用equals和使用==会得到同样的结果,如果比较的是两个独立的对象则总返回false。如果你编写的类希望能够比较该类创建的两个实例对象的内容是否相同,那么你必须覆盖equals方法,由你自己写代码来决定在什么情况即可以认为两个对象的内容是相同的。

      

     示例代码:

public class Test {   
    public static void main(String[] args) {   
        Integer p = 1;   

         Integer q = 1;
        Integer i = new Integer(1);   

         Integer j = new Integer(1);
        if(p == q){   
             System.out.println("integer:p == q"); //实际结果
         }else{   
             System.out.println("integer:p != q");   
         }

        if(p.equals(q)){
             System.out.println("integer:p.equals(q)"); //实际结果

         }else{   
             System.out.println("integer:p.equals(q)");

         }

        if(i == j){   
             System.out.println("int:i == j");   
         }else{   
             System.out.println("int:i != j"); //实际结果

         }   
        if(i.equals(j)){   
             System.out.println("integer:i.equals(j)");//实际结果

         }else{

             System.out.println("integer:!i.equals(j)");

         }   
         String a = "abc";   
         String b = "abc";   
         String c = new String("abc");   
         String d = new String("abc");   
        if(a == b){   
             System.out.println("abc对象相等"); //实际结果
         }else{   
             System.out.println("abc对象不相等");   
         }   
        if(a.equals(b)){   
             System.out.println("ab相等"); //实际结果

         }else{   
             System.out.println("ab不相等");   
         }   
        if(c.equals(d)){   
             System.out.println("cd相等"); //实际结果
         }else{   
             System.out.println("cd不相等");   
         }   
        if(c == d){   
             System.out.println("cd对象相等");   
         }else{   
             System.out.println("cd对象不相等"); //实际结果
         }   
     }   
   
}

中软国际电子政务部Jeff Chi总结,转载请说明出处。

----------------------------------------------------------------------------------


深入探讨equals:

===================
转自硅谷动力

equals方法的重要性毋须多言,只要你想比较两个对象是不是同一对象,你就应该实现equals方法,让对象用你认为相等的条件来进行比较.

下面的内容只是API的规范,没有什么太高深的意义,但我之所以最先把它列在这儿,是因为这些规范在事实中并不是真正能保证得到实现.

1.对于任何引用类型, o.equals(o) == true成立.

2.如果 o.equals(o1) == true 成立,那么o1.equals(o)==true也一定要成立.

3.如果 o.equals(o1) == true 成立且 o.equals(o2) == true 成立,那么

o1.equals(o2) == true 也成立.

4.如果第一次调用o.equals(o1) == true成立,在o和o1没有改变的情况下以后的任何次调用都成立.

5.o.equals(null) == true 任何时间都不成立.

以上几条规则并不是最完整的表述,详细的请参见API文档.对于Object类,它提供了一个最最严密的实现,那就是只有是同一对象时,equals方法才返回true,也就是人们常说的引用比较而不是值比较.这个实现严密得已经没有什么实际的意义, 所以在具体子类(相对于Object来说)中,如果我们要进行对象的值比较,就必须实现自己的equals方法.先来看一下以下这段程序:

public boolean equals(Object obj)

{

if (obj == null) return false;

if (!(obj instanceof FieldPosition))

return false;

FieldPosition other = (FieldPosition) obj;

if (attribute == null) {

if (other.attribute != null) {

return false;

}

}

else if (!attribute.equals(other.attribute)) {

return false;

}

return (beginIndex == other.beginIndex

& endIndex == other.endIndex

&& field == other.field);

}



作者: 清心玉质    时间: 2013-7-19 23:06
“==”用在比较两个简单的数据类型的值是否相等,比如int a =9; int b=9; a==b,就是true;“==”用在引用型变量的时候,表示引用的地址值是否相等,如:class a = new class("123"); class b =new class("123");
a==b;这里就判断两个引用 a和b的地址值是否相等,答案是false。

而equals判断的是对象的内容是否相等,a.equals(b)就是判断两个对象的内容是否相等,答案是true
作者: 白_蓝(八公)    时间: 2013-7-19 23:20
哥们!你应该已经有堆和栈的概念了吧!我就直接说了哈~==比较的是栈中指向堆内存的指向---也就是地址值的比较~所以可能你发现比较的两个值明明相同哈~可返回的为什么是false,因为==比较的是地址值!而我们想要去比较那两个值的内容啊~所以提供了一个方法euqals()方法!像有String s1=2;String s2=2;如果你是s1==s2的话会返回false,因为比较不是2这个值,而是他们在堆内存的地址值,而我们这样:s1.euqals(s2)---->那么返回就会是true了!希望对你有帮主哈
作者: 吴清源    时间: 2013-7-20 10:31
  1. public class Student {
  2. public int id;
  3. public String name;
  4. public Student(int id,String name) {
  5. this.id = id;
  6. this.name = name;
  7. }
  8. boolean equals(Student student) { //重写了Object的equals方法,让其比较id值
  9. if (student.id == this.id) {
  10. return true;
  11. }
  12. return false;
  13. }
  14. public static void main(String args[]) {
  15. Student st1 = new Student(2,"xiaoming");
  16. Student st2 =new Student(8,"xiaohong");
  17. Student st3 = new Student(2,"xiaohei");
  18. System.out.println("用==进行比较:"+ (st1==st2));
  19. System.out.println("用==进行比较:"+ (st1==st3)); //进行地址引用的比较,始终返回false
  20. System.out.println("用equals进行比较:"+ st1.equals(st2));
  21. System.out.println("用equals进行比较:"+ st1.equals(st3)); //id相同,返回true
  22. }
  23. }
复制代码
这里写了个例子,重写了equals方法,==在比较对象类型时比较的是引用的地址值,equals根据你的重写来进行比较。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2