equals和==的区别

来源:互联网 发布:linux ftp服务 编辑:程序博客网 时间:2024/06/10 20:19

1 == 

对于==,如果作用于基本数据类型(byte,short,char,int,long,float,double,boolean)的变量,则直接比较其存储的 “值”是否相等;如果作用于引用类型的变量,则比较的是所指向的对象的地址。

2 equals

equals方法不能作用于基本数据类型的变量。如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址。

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

3 Java中经常用来做比较的是字符串,下面我们来看看字符串的比较


首先我们先看下String的重写的equals()方法的源码:
 
  /**     * Compares this string to the specified object.  The result is {@code     * true} if and only if the argument is not {@code null} and is a {@code     * String} object that represents the same sequence of characters as this     * object.     *     * @param  anObject     *         The object to compare this {@code String} against     *     * @return  {@code true} if the given object represents a {@code String}     *          equivalent to this string, {@code false} otherwise     *     * @see  #compareTo(String)     * @see  #equalsIgnoreCase(String)     */    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的equals方法先比较两个对象的内存 地址,若一样,则返回true,否则进行下一步操作,判断传入参数是否为String对象,若是,则获取对象的长
度,若一样,则获取参数对象的char[]与原对象的char[]进行比较,若每个子元素都一样则返回true,否则返回false;
    
3.1

String str1 = "hello";String str2 = "hello";System.out.println(str1.equals(str2));System.out.println(str1 == str2);

输出结果是:truetrue

String的equals()是比较字符串的内容,所以输出的结果是true。==是比较内存地址的,结果也是true,说明str1和str2的地址相同。

但是为啥地址相同呢?


Java有常量池,存储所有的字符串常量。String str1 = “hello”,java首先会在常量池查找是否有 “hello”这个常量,发现没有,于是会

创建一个 “hello”,并将其赋给str1。接着String str2= “hello,java同样会在常量池中查找 “hello”,这次常量池中已经有str1创建的 “h

ello”,所以不创建新的常量,将其地址赋给str2。因此,str1和str2就有了相同的地址。


3.2 new建立String对象

String str1 ="hello";String str2 =new String("hello");String str3 =new String("hello");System.out.println(str1.equals(str2));System.out.println(str1==str2);System.out.println(str2==str3);

/**

output 输出

true

false

false

*/


new String()每次会在堆中创建一个对象,每次创建的对象内存地址都不同,故==不相等。但字符串内容是相同的,故equals()相等。


3.3 利用intern

String s1="Monday";String s2 =new String("Monday");s2 = s2.intern();System.out.println(s1.equals(s2));System.out.println(s1==s2);

输出结果为 true true

这是为什么?

java.lang.string 的intern()方法 返回的还是 s2的字符串,看上去没啥改变,但是它会检查常量池里面有没有字符串s2,

若有则将原先字符串的引用给s2,若没有则将字符串s2添加到常量池中,再将引用返回给s2


0 0