之equals和==区别

原文链接:http://www.cnblogs.com/gyjx2016/p/7412876.html


Java中数据类型可以分为两类

1、基本数据类型(byte,short,char,int,float,double,long,boolean)

2、复合数据类型(类,String等)

Δ在基本数据类型中他们之间的比较,是==比较他们的值,当使用==来判断两个变量是否相等的时候,如果是基本数据类型,值相等,那么就返回true,如下代码:

Δ在复合数据类型中当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址所以除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false

JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地址(this==obj),但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。

对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,因为Object的equals方法也是用双等号(==)进行比较的,所以比较后的结果跟双等号(==)的结果相同。如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class  Person{
     private  String name;
     public  String getName() {
         return  name;
     }
     public  void  setName(String name) {
         this .name = name;
     }
     public  Person(String name) {
         super ();
         this .name = name;
     }
     public  Person() {
         super ();
     }
}

 

1
2
3
4
5
6
7
@Test
public  void  test02(){
     Person p1= new  Person( "张三" );
     Person p2= new  Person( "张三" );
     System.out.println(p1==p2);
     System.out.println(p1.equals(p2));
}

返回结果:false,false

那么我们再看一段代码

1
2
3
4
5
6
7
@Test
public  void  test03(){
     String s1= new  String( "abc" );
     String s2= new  String( "abc" );
     System.out.println(s1==s2);
     System.out.println(s1.equals(s2));
}

 返回结果:false,true

因为String将equals重写了,看重写之后的JDK代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public  boolean  equals(Object anObject) {
        if  ( this  == anObject) {
            return  true ;
        }
        if  (anObject  instanceof  String) {
            String anotherString = (String)anObject;
            int  n = value.length;
            if  (n == anotherString.value.length) {
                char  v1[] = value;
                char  v2[] = anotherString.value;
                int  i =  0 ;
                while  (n-- !=  0 ) {
                    if  (v1[i] != v2[i])
                        return  false ;
                    i++;
                }
                return  true ;
            }
        }
        return  false ;
    }

 因为String底层实际存储是char数组,所以,JDK是while一个个索引的比较值,只要值相等,那么即返回true

那么我们再看这段代码:

1
2
3
4
5
6
7
@Test
public  void  test03(){
     String s1= "abc" ;
     String s2= "abc" ;
     System.out.println(s1==s2);
     System.out.println(s1.equals(s2));
}

返回true,true,因为s1,s2都引用同一个String对象abc,内存指向相等故返回true,这里需要解释的是字符串缓存池的概念,在s2="abc"时,程序会先到String缓存池中寻找有相同值的对象,找到之后直接引用!

那么再看一段代码

1
2
3
4
5
6
7
@Test
public  void  test03(){
     String s1= "abc" ;
     String s2= new  String( "abc" );
     System.out.println(s1==s2);
     System.out.println(s1.equals(s2));
}

返回,false,true

因为s2创建一个新的abc对象在内存中,值相同但是位置不同!

再看一段代码

1
2
3
4
5
6
7
8
@Test
public  void  test03(){
     String s1= "abc" ;
     String s2= new  String( "abc" );
     s2=s2.intern();
     System.out.println(s1==s2);
     System.out.println(s1.equals(s2));
}

返回true,true,看一下intern背后做的哪些工作?,看源码说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
      * Returns a canonical representation for the string object.
      * <p>
      * A pool of strings, initially empty, is maintained privately by the
      * class {@code String}.
      * <p>
      * When the intern method is invoked, if the pool already contains a
      * string equal to this {@code String} object as determined by
      * the {@link #equals(Object)} method, then the string from the pool is
      * returned. Otherwise, this {@code String} object is added to the
      * pool and a reference to this {@code String} object is returned.
      * <p>
      * It follows that for any two strings {@code s} and {@code t},
      * {@code s.intern() == t.intern()} is {@code true}
      * if and only if {@code s.equals(t)} is {@code true}.
      * <p>
      * All literal strings and string-valued constant expressions are
      * interned. String literals are defined in section 3.10.5 of the
      * <cite>The Java™ Language Specification</cite>.
      *
      * @return  a string that has the same contents as this string, but is
      *          guaranteed to be from a pool of unique strings.
      */
     public  native  String intern();

 

1
2
3
4
5
* When the intern method is invoked,  if  the pool already contains a
* string equal to  this  { @code  String} object as determined by
* the { @link  #equals(Object)} method, then the string from the pool is
* returned. Otherwise,  this  { @code  String} object is added to the
* pool and a reference to  this  { @code  String} object is returned.

这句话意思:如果池中包含一个字符串等于对象所引用的对象方法,那么直接从池中返回

所以上面代码最后返回true,true!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值