jdk8和11中equals区别比较(String.equals)

jdk8和11中equals区别比较(String.equals)

实例

test.java

public class test {
    public static void main(String[] args) {
        String a = "abcde";
        System.out.println("a为"+a);
        String b = "abcde";
        System.out.println("b为"+b);
        String c = new String("abcde");
        System.out.println("c为"+c);

        System.out.println("a==b的结果是:" + (a == b));
        System.out.println("a.equals(b)的结果是:" + a.equals(b));

        System.out.println("a==b的结果是:" + (a == c));
        System.out.println("a.equals(b)的结果是:" + a.equals(c));

    }
}

输出

a为abcde
b为abcde
c为abcde
a==b的结果是:true
a.equals(b)的结果是:true
a==b的结果是:false
a.equals(b)的结果是:true

结果为a和b无论"=="还是equals结果都为true,而a和c的"=="为false,equals为true,下面展开分析

"=="的比较原理

在编译String a=“abcde"的时候其实是jvm在常量池中创建了一个内容为"abcde"的地址值,然后让a去指向"abcde”,而不是把"abcde"直接赋值给a;
在编译String b=“abcde"的时候常量池中已经有了"abcde"的地址值,所以让b直接指向常量池中的"abcde”,这样a和b的地址值都是常量池中"abcde"的地址值,所以通过双等号的运算结果是true。

在执行String c = new String(“abcde”);时,在堆内存中重新开辟了一块空间来存储"abcde",导致a和c的地址不同,所以"=="结果为false

也就是说,"=="比较引用数据类型(String),比较的是内存中的地址,而比较基本数据类型时,比较的是值,不过,由于java中只有值传递,因此==比较的都是值,比较地址时,不过是把地址作为值传递

equals的比较原理(jdk1.8)

这里直接看jdk1.8中equals的源码,非常清晰明了

public boolean equals(Object anObject) {
        if (this == anObject) {  //this为a,anObject为c,第一步还是使用"=="比较a和c的地址值
            return true;  //地址不同则往下
        }
        if (anObject instanceof String) { //判断c是否是String的实例,不是则直接false
            String anotherString = (String)anObject; //转型
            int n = value.length; //此处省略this,实际n为a的长度
            if (n == anotherString.value.length) { //若长度不等直接false
                char v1[] = value; //将a转为字符数组
                char v2[] = anotherString.value; //将c转为字符数组
                int i = 0;
                while (n-- != 0) { //for循环,内容不等则直接false
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

简单来说,equals还是走的"“比较地址,不过比”"多了匹配内容的步骤

equals的比较原理(jdk11)

上源码

 public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String aString = (String)anObject;
            if (coder() == aString.coder()) {
                return isLatin1() ? StringLatin1.equals(value, aString.value)
                                  : StringUTF16.equals(value, aString.value);
            }
        }
        return false;
    }

jdk11与jdk8大同小异,不过添加了一些额外的步骤,如第一个是if (coder() == aString.coder())

coder()源码如下:

byte coder() {
        return COMPACT_STRINGS ? coder : UTF16; 
    }

COMPACT_STRINGS默认值为true,coder默认值为0,UTF16默认值为1,因此coder()方法返回值为0

isLatin1()源码如下:

private boolean isLatin1() {
    return COMPACT_STRINGS && coder == LATIN1;
}
@Native static final byte LATIN1 = 0;

COMPACT_STRINGS默认值为true,coder默认值为0,LATIN1默认值为0,因此isLatin1()返回值为true

StringLatin1.equals(value, aString.value)方法源码如下,和jdk8一模一样就不多解释了

 @HotSpotIntrinsicCandidate
    public static boolean equals(byte[] value, byte[] other) {
        if (value.length == other.length) {
            for (int i = 0; i < value.length; i++) {
                if (value[i] != other[i]) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

总结

从源码分析可见jdk8和jdk11中对于equals的代码没有本质变动,都是先使用"=="比较其地址值,然后再比较其属性

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Acerola-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值