首页 > 代码库 > ==和equals
==和equals
前两天偶然听到关于==和equals的讨论,编程中也经常用这两种,仔细一想,理解有限,所以稍作分析,要了解这两个的区别,首先要知道内存中的堆和栈,如下图:
基本类型的变量名和值、对象的地址存放在空间较小的栈中,对象内容存放在空间较大的堆中。
==和equals区别
equals的定义
要知道equals的作用,首先要知道JAVA中“万象之宗”的Object,Object中声明了equals及实现,查看API文档,发现最主要的一段内容:
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).
equals的例外
虽然所有对象默认继承自Object,但是部分类重写了Object的equals,如String、Math,来看一下String的equals定义:
Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.
==的定义
使用"=="比较变量时,比较的是变量在栈中保存的值。专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相当,只能用==操作符。简单实例
分别测试:
- 引用类型dog的==和equals
- 使用构造器的String的==和equals
- 不使用构造器的String的==和equals
代码
public class testEquals { public static void main(String []args) { dog aDog=new dog( ); dog bDog=new dog( ); //测试对象类型dog的== if(aDog==bDog) { System.out.println( "aDog==bDog?true"); } else { System.out.println( "aDog==bDog?false"); } //测试对象类型的equals if ( aDog.equals( bDog ) ) { System.out.println( "aDog.equals( bDog )?true"); } else { System.out.println( "aDog.equals( bDog )?false"); } //测试String对象的== String s1=new String( "i am a string"); String s2=new String( "i am a string"); if ( s1==s2 ) { System.out.println( "s1==s2?true"); } else { System.out.println( "s1==s2?false"); } //测试String对象的equals String s3=new String( "i am a string"); String s4=new String( "i am a string"); if ( s3.equals(s4) ) { System.out.println( "s3.equals(s4) ?true"); } else { System.out.println( "s3.equals(s4) ?false"); } //测试基础类型String的== String s5="123"; String s6="123"; if ( s5==s6 ) { System.out.println( "s5==s6?true"); } else { System.out.println( "s5==s6?false"); } //测试基础类型String的equals String s7="456"; String s8="456"; if ( s7.equals(s8) ) { System.out.println( "s7.equals(s8)?true"); } else { System.out.println( "s7.equals(s8)?false"); } } }
测试结果
aDog==bDog?false aDog.equals( bDog )?false s1==s2?false s3.equals(s4) ?true s5==s6?true s7.equals(s8)?true
简单分析
- dog为引用类型,当使用==比较时,比较的是两个对象在栈中保存的地址,所以为false。
- dog为引用类型,当使用equals时,默认采用Object的equals,比较的是两个对象的引用地址,所以仍然为false。
- 当String采用构造器的方式,使用==比较时,比较的仍然是两个对象在栈中保存的引用地址,所以为false。
- 当String采用构造器的方式,使用equals时,因为String重写了equals方法,比较的是两个对象中保存的值,所以此时为true。
- 当String不使用作基本类型使用时,比较的均为在栈中保存的值,所以都为true。
总结
一句话总结,==比较的是在栈中保存的内容(地址或值),而equals在默认状态下比较的也是保存在栈中的内容,但是有些类重写了equals方法,比较的是堆中的内容。