==和equals

来源:互联网 发布:微信大数据分析工具 编辑:程序博客网 时间:2024/05/24 06:30

    前两天偶然听到关于==和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).

    也就是说当x和y均指向相同的对象时,即栈中保存的值相同时,x.equals(y)才为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.

    在String中,equals被重写,实现变为:当对象x和y的字符序列相同时,则x.equals(y)为true,不再比较x和y对象的地址。

    ==的定义

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

简单实例

    分别测试:

  • 引用类型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");}//测试对象类型的equalsif ( 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对象的equalsString 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的equalsString 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?falseaDog.equals( bDog )?falses1==s2?falses3.equals(s4) ?trues5==s6?trues7.equals(s8)?true

简单分析

  • dog为引用类型,当使用==比较时,比较的是两个对象在栈中保存的地址,所以为false。
  • dog为引用类型,当使用equals时,默认采用Object的equals,比较的是两个对象的引用地址,所以仍然为false。
  • 当String采用构造器的方式,使用==比较时,比较的仍然是两个对象在栈中保存的引用地址,所以为false。
  • 当String采用构造器的方式,使用equals时,因为String重写了equals方法,比较的是两个对象中保存的值,所以此时为true。
  • 当String不使用作基本类型使用时,比较的均为在栈中保存的值,所以都为true。

总结

    一句话总结,==比较的是在栈中保存的内容(地址或值),而equals在默认状态下比较的也是保存在栈中的内容,但是有些类重写了equals方法,比较的是堆中的内容。



1 0
原创粉丝点击