Equals和==的区别

2021-01-07  本文已影响0人  8爪章鱼

当我们看到这个面试题的时候,相信大多数同学脑海中浮现的肯定是 == 比较的是引用,equals比较的是值,但是真实情况,equal是简单的比较值吗?下面我们通过看下equals的源码来分析一下:

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

首先在代码刚开始的位置使用了==,这代码如果两个对象的引用地址地址是相同的,那么默认对象的值也是相等的。

后面判断如果传入的是String 对象,那么就对String对象中的每个char进行元素比较,如果全相等,那两个对象就相等。

为什么String的equals方法之所以比较的是值?大家有没有明白了?

因此,String中equals的比较可以用下图来演示:

内存地址分配

特殊的String定义

String除了通过new的形式进行定义,还可以通过等号赋值的形式:

String str = "10";

这是一种非常特殊的形式,不需要new就可以产生对象,和new有本质的区别。

String str = "10"
String str1 = "10";
String str2 = new String("10");
System.out.println(str == str1);  // return true
System.out.println(str == str2);  // return false
System.out.println(str.equals(str1));  // return true
System.out.println(str.equals(str2));  // return false

要想理解上面第四行为什么==也会返回True,我们需要深入理解下JVM内存分配管理方式

JVM内存分布

当我们定义了一个String str = "10" , 相当于我们定义了一个字符串常量,并没有去New一个字符串对象,这种形式的赋值存在于常量池中,而不是像new一样存放在堆中。当声明这样一个字符串时,JVM会在常量池中先查找有没有对应值的对象。如果有,把它赋给当前引用,即原来的引用和现在的引用指向了同一对象。如果没有,则在常量池中新创建一个对象,以这形式声明的字符串,只要值相等,任何多个引用都指向同一对象,而new形式创建String对象是每次调用就产生一个新的对象。

上一篇下一篇

猜你喜欢

热点阅读