equals和==的区别

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


输出结果是: true true

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值