Java中“==”和“euqals”方法的区别

一:“==”的用法

来看下面的代码:

// 基本数据类型
int n =3;
int m=3;
System.out.println(n==m);

//引用类型  
String str = new String("abc");

String str1 = new String("abc");

String str1 = new String("abc");

System.out.println(str1==str2);

str1 = str ;
str2 = str;
System.out.println(str1==str2);

输出结果为true,false,true。

在解释之前,我们先介绍Java中的8大基本数据类型

  • 整形类:  byte、short、int、long
  • 浮点型: float、double
  • 字符类:  char
  • 布尔类型: boolean

这几种都是基本类型,“==”比较基本类型的变量时比较的是赋予变量的值,运行下面的语句:

int n = 3;

int m = 3;

两个int类型的变量被赋予的值都是3。所以第一个输出语句中”n==m"判定结果为true。

对于非基本类型的变量,就是引用对象类型的变量,比如上例中的“str”变量,其存储的不是一个“值”,而是new出来的对象在内存中的地址(JVM虚拟机内存)。此时"==“比较的是两个变量在内存中的地址。

比如下面这个语句:

String str1; 

该语句此时只是声明了一个String引用类型的变量,并没有任何对象指向它,接下来可以通过一个new语句创建一个String类型的对象,然后与之前的对象变量str1进行绑定。

上例代码中,String类型的变量str1和str2都用了一个new语句,此时在内存中建立的是两个对象,在内存中的地址不同,他们就像两个双胞胎,是两个不同的实例。所以第二个输出语句中”str1==str2"判定结果为false。

接下里继续运行下面的语句:

str1 = str;
str2 = str;

这两个语句使str1和str2都指向了str指向的地址,所以此时变量str1和变量str2指向的地址相同(准确来说是三者都相同,还有str),所以第三个输出语句中“str1==str2"的判定结果为true。

二:”equals"的用法

equals方法是基类(父类)Object中的方法,因此对于所有的继承于Object的类都会有该方法。来看一下源代码中Object类的equals方法的实现:

public boolean equals(Object obj){
    return(this==obj);
}

显而易见,在基类Object类中,equlas方法比较的是对象在内存中存储的地址,与“==”相似,但无法比较基本类型的变量。

看到这儿可能会有觉得既然Obiect类中的equals方法与“==”类似,而且只能比较引用类型的变量,那为什么还要用equals方法?老师上课还要讲这个,咱也不知道为啥要讲这个“没用”的方法,咱也不敢问。。。

但是细心的会发现刚刚看的源码是基类Object类中的equals方法的实现,基类中的方法是可以被Java中的很多类进行重写的。

来一起看下面这个代码:

public static void main(String[] args){

    String str1 = new String("abc");

    String str2 = new String("abc");

    System.out.println(str1.equals(str2));
    
}

这里的运行结果为true。

因为变量str1和str2都是String类型的变量,他们所调用的equals方法是String中重写的equals方法。

来看一下String类的equals方法的源码:

public boolean equals(Object anObject){
    if(this==anObject){
        return false;
    }
    if(anObject instanceof String){
        String anotherString = (String)anObject;
        int n = value.length;
        if(n==anotherString.value.length){
            char1 v1[]=value;
            char2 v2[]=anotherString.value;
            int i=0;
            while(n-- !0){
                if(v1[i]!=v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

可以看出,String类对equals方法重写后,此时的equals方法比较的是指向的两个字符串对象所存储的字符串是否相等。

其他的一些类比如Double,Date等,也对equals方法进行了重写,用来比较指向的对象所存储的内容是否相等。

最后总结一下:

一:对于“==”,如果比较的是两个基本类型的变量,那比较的就是他们两个的值;如果比较的是对象引用类型的变量,那比较的就是他们在存储在内存中的地址。

二:对于“equals”方法,首先注意它不可以比较两个基本类型的变量。如果没有对它进行重写,那比较的就是所指向的对象的地址。如果像是String类、Integer类等重写了equals方法,那比较的就是所指向的对象的内容。

Guess you like

Origin blog.csdn.net/qq_40805639/article/details/117570517