Java基础之equals方法

1、关于equals方法

equals方法是基类Object中的方法,因此对于所有的继承于Object的类都会有该方法。为了更直观地理解equals方法的作用,直接看Object类中equals方法的实现。该方法定义在Object类中,其源码如下:

/**
*Object.class
*/
public boolean equals(Object obj) {
        return this == obj;
    }

很显然,在Object类中,equals方法是用来比较两个对象的引用是否相等,即是否指向同一个对象。

2、关于字符串的比较

先看如下代码:

public class Main { 
    public static void main(String[] args) {
        String str1 = "abcd";//line 1
        String str2 = new String(str1);// line 2
        String str3 = "abcd";//line 3
        String str4 = new String("abcd"); //line 4
        String str5 = str1;//line 5
        str5 = str5.concat("ef");//line 6
        System.out.println(str1==str3);        
        System.out.println(str1==str2);              
        System.out.println(str2==str4);        
        System.out.println(str1==str5);
        System.out.println(str1.equals(str3));
        System.out.println(str1.equals(str2)); 
        System.out.println(str2.equals(str4));
        System.out.println(str1.equals(str5));
    }
}

由上一篇博客Java基础之String可知后四行的打印结果为:true,true,true,fasle,对于最后一个false结果比较容易理解,str1的字符串内容为“adcd”,str5的内容为“abcdef”,两者显然不相同,故结果为false,而对于前三个结果,又该如何解释呢?
先看String类源码中的equals方法:

/**
*String.class
*/
public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj instanceof String) {
            String s = (String) obj;
            int i = value.length;
            if (i == s.value.length) {
                char ac[] = value;
                char ac1[] = s.value;
                for (int j = 0; i-- != 0; j++)
                    if (ac[j] != ac1[j])
                        return false;
                return true;
            }
        }
        return false;
    }

看到这里我们应该明白了,原来String类对equals方法进行了覆写,用来比较指向的字符串对象所存储的字符串是否相等,从String类的equals方法可知,在equals方法中先进行引用对象的比较,如果两者指向的内存空间相同,及两者指向的为同一内存空间,字符串内容一定相同,直接返回true,如果两者指向的内存空间不同,在进行字符串内容的比较,如果内容完全相同,直接返回true,否则返回false。

3、关于其他类型

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

4、关于关系操作符“==”

关于关系操作符“==”在《Java编程思想》中有这样一句描述:
关系操作符生成的是一个boolean结果,它们计算的是操作数的值之间的关系
先看如下代码:

public class Main { 
    /**
     * @param args
     */
    public static void main(String[] args) {
        int m=3; 
        int n=3;      
        System.out.println(m==n); 
        String str = new String("hello");
        String str1 = new String("hello");
        String str2 = new String("hello"); 
        System.out.println(str1==str2); 
        str1 = str;
        str2 = str;
        System.out.println(str1==str2);
    } 
}

输出结果为 true false true;

  • 对于基本数据类型的变量,变量直接存储的是“值”,因此在用关系操作符==来进行比较时,比较的就是 “值” 本身。
  • 对于引用数据类型的变量,变量存储的是关联的对象在内存中的地址,str,str1,str2分别指向了一个String对象,此时str,str1,str2成为对象的引用,变量str,str1,str2中存储的是它们指向的对象在堆内存中的地址,并不是对象的“值”本身,也就是说并不是直接存储的字符串”hello”。因此在用==对str1和str2进行第一次比较时,得到的结果是false。因此它们分别指向的是不同的对象,也就是说它们实际存储的内存地址不同。
    而在第二次比较时,都让str1和str2指向了str指向的对象,那么得到的结果毫无疑问是true。

5、总结

  • 对于==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;如果作用于引用类型的变量,则比较的是所指向的对象的地址;
  • 对于equals方法,注意:equals方法不能作用于基本数据类型的变量,如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。

你可能感兴趣的:(Java基础之equals方法)