== 和 equals 的区别是什么?

本文详细解析了Java中String对象使用==和equals方法进行比较时的区别。通过实例展示了字符串对象在内存中的存储状态,解释了为什么在不同情况下比较结果不同。同时提到了String的intern()方法以及Integer类中equals方法的实现,进一步阐述了基本类型与引用类型在比较时的差异。

== 和 equals 的区别是什么?

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

打印结果:

false
true
false
   		System.out.println(str1.equals(str2));
        System.out.println(str1.equals(str3));
        System.out.println(str3.equals(str2));

打印结果:

true
true
true

原因:

在java中我们一般把对象存放在堆区,把对象的引用放在栈区。因此上面三个字符串的内存状态应该是下面这样的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nzPgqJg7-1652004541711)(==和equals理解.assets/2196036-20201030134224933-1426175138.png)]

现在明白了:
(1)String str1 = "Hello"会在堆区存放一个字符串对象
(2)String str2 = new String(“Hello”)会在堆区再次存放一个字符串对象
(3)String str3 = str2这时候Str3和Str2是两个不同的引用,但是指向同一个对象。

根据这张图再来看上面的比较:
(1)str1 == str2吗?意思是地址指向的是同一块地方吗?很明显不一样。
(2)str1 == str3吗?意思是地址指向的是同一块地方吗?很明显不一样。
(3)str2 == str3吗?意思是地址指向的是同一块地方吗?很明显内容一样,所以为true。
(4)str1.equals(str2)吗?意思是地址指向的内容一样吗?一样。
(5)str1.equals(str3)吗?意思是地址指向的内容一样吗?一样。
(6)str2.equals(str3)吗?意思是地址指向的内容一样吗?一样。

总结:

(1)基本类型比较:
①使用双等号 == 比较的是值是否相等。
②基本数据类型无equals方法(没有意义)。
(2)引用类型比较:
①重写了equals方法,比如String。
第一种情况:使用==比较的是String的引用是否指向了同一块内存
第二种情况:使用equals比较的是String的引用的对象内容是否相等
②没有重写equals方法,比如User等自定义类。
==和equals比较的都是引用是否指向了同一块内存

注意:

字符串提供了intern 方法,意思是检查字符串池里是否存在,如果存在了那就直接返回为true。因此在这里首先s1会在字符串池里面有一个,然后 s2.intern()一看池子里有了,就不再新建了,直接把s2指向它。

// 字面值每次都会先检查内存中是否有此字符串
//如果有则不创建字符串对象直接返回。
	String str1 = "hello";
	
// new关键字创建【每次都会创建一个新的字符串对象】
  String str2 = new String("hello");

 				str2 = str2.intern();
        System.out.println(str1 == str2);//true
        System.out.println(str1.equals(str2));//true

我们进到Integer的equals看一看:

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return this.value == (Integer)obj;
    } else {
        return false;
    }
}

会发现内部使用的是用进行比较,这里号两边一个是基本数据类型,一个是Integer包装类型,因此会进行一个自动拆箱的过程,编译器会调用Integer的intValue()方法,然后比较两个的值,所以这里的equals比较的就是值

其余和Integer同类型的包装类内部有各自对equals方法的重写方式,例如Long:

public boolean equals(Object obj) {
   if (obj instanceof Long) {
       return this.value == (Long)obj;
   } else {
       return false;
   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

YD_1989

分享不易,非常感谢您的鼓励支持

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

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

打赏作者

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

抵扣说明:

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

余额充值