equals 和 == 号的区别

基本讲解:

基本类型的==比的是值,而不是对象,判断二者的内容是否相同。引用类型的==比较的是对象(内存地址)。

没有重写equals()的类一般是我们自定义的类。如果比较自定义类的对象,那么使用equals和使用==是一样的


equals操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。

==比较的是2个对象的地址,而equals比较的是2个对象的内容。

显然,当equals为true时,==不一定为true;

equals 方法比较的是两个对象的实际内容(先判断是不是同一个对象,然后判断内容是不是相等)

详细说明:

在Java中,时不时我们会把两个对象进行,然而得到的结果却不是我们想的结果,这是怎么回事呢?


一、两种形式的比较:比较时,我们要弄清楚是哪一种比较。   


 1.值类型比较     

即内容相同,我们就认为是相等的。比如:int i=5;int j =5;此时我们说i和j相等,其实指的是i和j的内容相同。  

   

2.引用类型比较    

但在Java中,除了值类型,另外还有一种引用类型,而不同的对象,其引用值其实并不相等,即在内存中的不同的地 址单元中。比如我们定义了学生类,分别有两个学生对象实例 :   

      Student stu= new Student();   Student stu1= new Student();


 此时我们无论是使用stu==stu1符号,或者stu.equals(stu1)方法,把两个对象进行比较,得到的结果都是不相等的,因为对于引用类型来说,默认是比较两个对象引用的地址,显示,每个对象的引用有自己唯一的地址,所以,是不相等。


二、有时,我们比较两个对象时,如果他们的内容一样,那么我们就认为这两个对象是相等的,如上面的两个学生对象。这时,我们该怎么办呢?其实,非常简单,只要在类里面重写equals()方法,进行对象里面的内容比较久可以了。如上面,我们只需要在Student类中重写equals()方法即可。    


下面,让我们来看看实例吧!     没有重写equals()方法时的比较:


学生类:Student类

[java] view plain copy
 print?
  1. package com.bluesky;  
  2.   
  3. public class Student {  
  4.       
  5.     String name;  
  6.       
  7.     public Student(){  
  8.           
  9.     }  
  10.       
  11.     public Student(String name){  
  12.           
  13.         this.name=name;  
  14.           
  15.     }</strong>  
  16.       
  17.   
  18. }</span>  

测试类Test:

[java] view plain copy
 print?
  1. package com.bluesky;  
  2.   
  3. public class Test {  
  4.   
  5.     public static void main(String[] args) {  
  6.   
  7.       int i=5;  
  8.       int j=5;  
  9.         
  10.       if(i==j) System.out.println("i和j相等!");  
  11.       else System.out.println("不相等!");  
  12.         
  13.       Student s = new Student("BlueSky");  
  14.       Student s1=new Student("BlueSky");  
  15.         
  16.       if(s==s1)  System.out.println("s和是s1相等!");  
  17.       else System.out.println("s和是s1不相等!");  
  18.         
  19.       if(s.equals(s1)) System.out.println("s和是s1相等!");  
  20.       else System.out.println("s和是s1不相等!");  
  21.     }  
  22. }  

运行结果:

equals 和 == 号的区别

重写equals()方法后再次进行比较:

 Student类:

[java] view plain copy
 print?
  1. package com.bluesky;  
  2.   
  3. public class Student {  
  4.       
  5.     String name;  
  6.       
  7.     public Student(){  
  8.           
  9.     }  
  10.       
  11.     public Student(String name){  
  12.           
  13.         this.name=name;  
  14.           
  15.     }  
  16.   
  17.       
  18.     public boolean equals(Object obj) {  
  19.         if (this == obj)      //传入的对象就是它自己,如s.equals(s);肯定是相等的;  
  20.             return true;   
  21.         if (obj == null)     //如果传入的对象是空,肯定不相等  
  22.             return false;  
  23.         if (getClass() != obj.getClass())  //如果不是同一个类型的,如Studnet类和Animal类,  
  24.                                            //也不用比较了,肯定是不相等的  
  25.             return false;  
  26.         Student other = (Student) obj;       
  27.         if (name == null) {  
  28.             if (other.name != null)  
  29.                 return false;  
  30.         } else if (!name.equals(other.name))   //如果name属性相等,则相等  
  31.             return false;  
  32.         return true;  
  33.     }  
  34.       
  35.   
  36. }  

测试类Test:

[java] view plain copy
 print?
  1. package com.bluesky;  
  2.   
  3. public class Test {  
  4.   
  5.     public static void main(String[] args) {  
  6.   
  7.       int i=5;  
  8.       int j=5;  
  9.         
  10.       if(i==j) System.out.println("i和j相等!");  
  11.       else System.out.println("不相等!");  
  12.         
  13.       Student s = new Student("BlueSky");  
  14.       Student s1=new Student("BlueSky");  
  15.         
  16.       if(s==s1)  System.out.println("s和是s1相等!");  
  17.       else System.out.println("s和是s1不相等!");  
  18.         
  19.       if(s.equals(s1)) System.out.println("s和是s1相等!");  
  20.       else System.out.println("s和是s1不相等!");  
  21.     }  
  22. }  


运行结果:

equals 和 == 号的区别 


重写equals()方法后,得到s和s1相等。==对引用类型的只能进行地址比较,故还是不相等的。


再举例说明:


关于变量之间的比较,可以分为基础类型变量的比较和对象之间的比较。

对于基本类型来说,他们存储在jvm的栈中,因此比较的是变量的内容,也就是比较的变量的值。

equals 和 == 号的区别

对于引用类型来说,因为对象内容存储在jvm的堆中,栈中只是存储对象的引用(地址),无论是==还是equals比较的都是栈中的内容,即对象的引用,也就是比较的是两个对象的地址。但根据创建对象的方式不同可以分为两种情况:

1. 使用表达式创建对象:

equals 和 == 号的区别

2.使用new方法创建对象:

equals 和 == 号的区别

这里会引入两个新的问题:

1.为什么表达式创建和new创建,会让==比较产生不同的结果。

这是因为jvm在程序运行的时候会创建一个缓冲池,当使用表达式创建的时候,程序会在缓冲池中寻找相同值的对象,如果找到,就把这个对象的地址赋给当前创建的对象,因此,c和d实际上都指向了c的引用。因此在使用==时会返回true。

当用new创建对象时,是在堆中重新分配内存,因此栈中的引用是不相同的,所以,a和b引用的是值相同的不同对象。所以a==b返回false

2.既然equals比较的是引用,那么a.equals(b)为什么返回true。这是因为在Integer里,重写了equals方法!

equals 和 == 号的区别

我们可以自己创建一个类,并验证。

equals 和 == 号的区别

1.当自定义Value类中没有重写equals方法时,调用equals方法返回结果为false。说明此时equals比较的并不是内容。

2.重写equals方法。

equals 和 == 号的区别