简析Java中“==”与equals的区别

简析Java中“==”与equals的区别

因为之前在一些书上看到过有关的内容,个人觉得比较有趣,故在这里写一篇文章来表达一下个人的理解与看法。如有不恰当的地方,欢迎大家指出!

好了,话不多说,让我们进入正题吧。

首先,在Java中,“==”是一种操作符,而equals是一种方法。并且equals是直接来源于最初的object类。


Photo_1

从上图中我们可以看到equals方法的基本信息,下面来看具体代码:

public boolean equals(Object obj)
{
    return (this == obj);     //注意:在equals()方法里用的正是 “==”
}

由此我们知道,“ == ”与equals在本质上其实是一样的,都是依靠“==”进行处理。

这么看好像他们的确是一样的,不要急,让我们来看看下面的代码:

public static void main(String[] args)
{
  int t1=11, t2=22, t3=11;

  Boolean result1 = (t1==t2);   //(11不等于22,false)
  Boolean result2 = (t1==t3);   //(11等于11,true)

//  Boolean result3 = t1.equals(t2);(报错,基本类型不能调用equals方法)
//  Boolean result4 = t1.equals(t3);(报错,基本类型不能调用equals方法)

/**
 *  “equals”不能用于基本数据类型。只能用于类变量。对于基本数据类型要用其包装类。如:
 *  Integer t1 = new Integer(11);
 *  Integer t2 = new Integer(22);
 *  Integer t3 = new Integer(11);
 *  此时:
 *  result5 = t1.equals(t2)//(11不等于22,false)
 *  result6 = t1.equals(t3)//(11等于11,true)
 */

  String str1 = "aaa";
  String str2 = "aaa";
  String str3 = new String("aaa");

  Boolean result7 = (str1==str2);           //true
  Boolean result8 = (str1.equals(str2));    //true
  Boolean result9 = (str1==str3);           //false
  Boolean result10 = (str1.equals(str3));   //true

}

从这段代码中可以看出,当对象是基本数据类型的时候,“==”与equals都是判断基础数据类型的值是否相等。

但是,明明str1、str3的值都是“aaa”,为什么结果会不一样呢?

我们知道,“ == ”是判断变量(栈)内存中存放的对象(堆)的内存地址是否相等,在引用数据类型(如Sring类型)之中,“==”的作用是判断引用数据类型的地址是否相等。

很明显,str1与str3的地址是不一样的,因此“ == ”的结果为false;

但是为什么同样是用了“==”的equals的结果却为true呢?

其实,这里用的equals方法已经不是原来object类中的方法了,而是经过String类重写后新的equals方法,下面给出重写后的代码:

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;
}

从代码的第五行(即第二个if语句)中使用了instanceof关键字进行了对象类型的判断,也正是这里将equals方法从原方法改写为“比较两个String类变量的值”

在String中我们可以使用“==”比较地址值,所以再使用equals方法比较地址值意义不大,很多时候我们需要比较的是String具体的内容。所以String类中就进行了equals方法重写。String中重写之后的equals方法比较的就是具体的内容是否相同。

事实上,细心的朋友会发现,Object中的某些子类如数值包装类(Integer, Character, Double, Float等)、Data、File,它们也重写了Object类原有的equals方法,将其改为对比对象的内容,而不是空间地址。

当然!根据不同的需求,我们也可以给equals()赋予新的意义,此时只需要将equals方法重写即可。


最后,整理可得:

对于“==”
基本类型:比较的是值是否相同。
引用类型:比较的是地址值是否相同。


对于equals
只能比较引用类型。默认情况下,比较的是地址值是否相同。
大多数情况下都会被重写。(也包括使用者自己重写)

你可能感兴趣的:(简析Java中“==”与equals的区别)