您现在的位置是:首页 > 文章 > 浅谈Java中的equals和== 网站文章

浅谈Java中的equals和==

孙玉超 2019-11-05 13:40:45 0 评论 262 浏览 0 收藏 201 赞


前言:不要盲目的相信网上的博客教程,我更建议自己动手分析代码!


印象中我曾经面试过。。。噗,我曾经被面试过这个问题,当时的面试官给我的答案是:equals比较的是值,==比较的是地址。如此不严谨的回答,让我对这家公司的技术水平产生怀疑!正如下面代码显示的一样,想知道Java中==和equals的区别,我们还是应该先去根类Object看一下它的equals方法是怎么实现的。显而易见,其实在Object类中,equals方法返回的其实就是==的比较结果。


其实呢,在对Java基础体系比较熟悉的情况下。我们就会知道这个问题并不能简单的回答说equals比较的是值而==比较的是地址就结束了。这么回答只会让人觉得在敷衍,或者说对于这个问题根本不清楚。我们都知道equals是根类Object中的方法。其他类库基本上都重写了这个方法,比如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对象。也就是说如果两个String对象的地址相同,那么直接返回true,这段逻辑就是Object类中的那段代码。下面的代码对两个String对象进行字符遍历对比,每一个索引位置(字符串在内存中是一个字符数组)上的字符是不是相同。那么就很清楚了,equals到底如何比较取决于实现类如何重写。


说道这里不得不提一下,自我看过的所有相关文章,基本上说的都是对于基本类型(int,byte,……)“==” 比较的是值,引用类型比较的是地址,我是不同意这种理解的。我们知道Java中其实在一个方法内定义一个基本类型变量并初始化之后,再次定义一个相同字面量的变量其实并不会再次在栈中创建。例如:

void test(){
    int a = 9;
    int b = 9;//由于栈中已存在,就直接使用
}

所以对于基本类型,“==” 也是比较地址,它们在栈帧中位于同样的地址(好像是在局部变量表)。值得注意的是,此时修改b的值并不会影响a,因为b的指针指向了其他地方而已。


那么可能有人会问了,不同方法之间的基本数据类型变量比较呢?要知道Java中每一个方法的执行都是一个栈帧入栈的过程,每一个方法结束都是一个栈帧出栈的过程,所以方法内的局部变量生命周期都是非常短暂的,如果两个变量能够比较,那么当运行时,他们一定处于同一个栈帧,因为栈是线程私有的空间,即使作为参数传递过来,那也是当前栈帧的一个变量。


其他类的equals方法也都大相庭径,关键是看它重写的逻辑。这里也可以去看Integer等等类的源码对比equals重写的逻辑。那有没有想过,当我们自定义的类调用equals方法呢?显而易见,如果不重写equals的话,那么就等价于==。如果重写的话,那么就取决于我们重写的逻辑,但是这里又牵扯到重写equals方法时,hashcode方法的处理。我们说,重写equals方法一定要注意重写 hashcode() 方法。参考 为什么说重写equals()一定要重写hashcode()

转载请注明出处:转载请注明出处

上一篇 : 下一篇 :

留言评论

所有回复

暮色妖娆丶

96年草根站长,2019年接触互联网踏入Java开发岗位,喜欢前后端技术。对技术有强烈的渴望,2019年11月正式上线自己的个人博客