java中==和equals()的区别探究

目录

一、Object对象

二、==

三、String类的equals()方法

四、示例

4.1直接定义两个相同的值比较

4.2直接定义两个值不同的字符串进行比较

4.3直接定义一个字符串和new一个字符串进行比较(两者值相同)

4.4直接定义一个字符串和new一个字符串进行比较(两者值不同)

五、小扩展

六、总结:


|---------------------|
| 🎈边走、边悟🎈迟早会好 |

== 和 equals 有什么区别?这个问题本身不难,但是被问到的频率很高,且大部分人的回答都不够全面,让人听了有种"恨铁不成钢"的感觉,所以今天咱们就来好好聊聊这个问题。

一、Object对象

对于 Object 来说,其 equals 方法底层实现就是"==",如下 JDK 的 Object 源码如下:

java 复制代码
public boolean equals(Object obj) {
return (this == obj);
}

也就是说,对于 Object 对象来说,equals 和 == 都是一样的,都是比较对象的引用是否相同

二、==

  • 基本数据类型(也称原始数据类型) :byte,short,char,int,long,float,double,boolean。他们之间的比较,应用双等号(==),比较的是他们的值。
  • 引用数据类型:当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址(确切的说,是堆内存地址)。

注:对于引用数据类型种类型,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。因为每new一次,都会重新开辟堆内存空间。

三、String类的equals()方法

现在我们拿String类来举例:我们去\src\java\lang目录中找到String类,发现equals方法被重写如下:

java 复制代码
      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()方法其实是比较两个字符串的值是否相等。

  • 如果equals没有被重写,两种比较是相同的

  • 如果equals被重写了,那么两种比较自然不同

  • String内部默认重写了equals方法,所以:"==" 比较引用,equals 比较值

下面我们通过实际代码来看看String类的比较。

四、示例

("==" 比较引用,equals 比较值)

4.1直接定义两个相同的值比较
java 复制代码
String str1 = "tingyi";
String str2 = "tingyi";
System.out.println(str1 ==  str2); // true
System.out.println(str1.equals(str2)); // true

JDK1.7后:字符串常量池保存引用,常量池保存值

在创建字符串的时候,会先创建一个字符串缓冲池,当创建str1时,先在字符串常量池中寻找有没有对应"hello"的对象,如果没有,就创建一个,然后将str1对象放入字符串常量池中,将str1的值"hello"放入常量池中。

当创建str2时,先在字符串常量池中找有没有对应"hello"的对象,发现str1对应的值和自己要创建的字符串值相同,就直接引用str1所引用的对象

  1. 两者引用的对象相同,都是"hello",所以==为true
  2. 两者的值也相同,所以equals为true
4.2直接定义两个值不同的字符串进行比较
java 复制代码
String str1 = "tingyi";
String str2 = "ting";
System.out.println(str1 ==  str2); // false
System.out.println(str1.equals(str2)); // false
  1. 两者所引用的对象不同(引用的地址也就不一样),所以 str1 == str2 肯定为false
  2. 两者的值也不同,所以下面的也是false
4.3直接定义一个字符串和new一个字符串进行比较(两者值相同)
java 复制代码
String str1 = "Hello";
String str2 = new String("Hello");
System.out.println(str1 ==  str2); // false
System.out.println(str1.equals(str2)); // true
  1. 因为str2 new了一个新对象,所以和str1的引用不是同一个,所以==的比较为false
  2. 但是两者的值是相同的,所以equals的比较为 true
4.4直接定义一个字符串和new一个字符串进行比较(两者值不同)
java 复制代码
String str1 = "Hello";
String str2 = new String("Hi");
System.out.println(str1 ==  str2); // false
System.out.println(str1.equals(str2)); // false
  1. 因为str2 new了一个新对象,所以和str1的引用不是同一个,==的比较为false
  2. 两者的值是不相同的,所以equals的比较也为 false

五、小扩展

 public class ObjectDemo{
     public static void main(String[] args) {
         String s1 = "Hello";
         String s2 = new String("Hello");
         s2 = s2.intern();
         System.out.println(s1 == s2);       //  true
         System.out.println(s1.equals(s2));  //  true
     }
 }

上述代码的第5行中,java.lang.String的intern()方法"Hello".intern()方法的返回值还是字符串"Hello",表面上看起来好像这个方法没什么用处。

但实际上,它做了个小动作:检查字符串池里是否存在"abc"这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会 把"Hello"添加到字符串池中,然后再返回它的引用。

六、总结:

为了分析上面的代码,我们必须首先分析堆内存空间和栈内存空间,这一点非常重要:

  • ==:比较的是两个字符串内存地址(堆内存)的数值是否相等,属于数值比较;
  • equals():比较的是两个字符串的内容,属于内容比较。

🌟感谢支持 听忆.-CSDN博客

|--------------------|
| 🎈众口难调🎈从心就好 |

相关推荐
守护者17010 分钟前
JAVA学习-练习试用Java实现“使用Arrays.toString方法将数组转换为字符串并打印出来”
java·学习
源码哥_博纳软云12 分钟前
JAVA同城服务场馆门店预约系统支持H5小程序APP源码
java·开发语言·微信小程序·小程序·微信公众平台
禾高网络13 分钟前
租赁小程序成品|租赁系统搭建核心功能
java·人工智能·小程序
学会沉淀。19 分钟前
Docker学习
java·开发语言·学习
如若12320 分钟前
对文件内的文件名生成目录,方便查阅
java·前端·python
西猫雷婶1 小时前
python学opencv|读取图像(二十一)使用cv2.circle()绘制圆形进阶
开发语言·python·opencv
kiiila1 小时前
【Qt】对象树(生命周期管理)和字符集(cout打印乱码问题)
开发语言·qt
初晴~1 小时前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
做网站建设制作设计小程序推广1 小时前
武汉做网站优化推广效果的科学评估方法
经验分享
小_太_阳1 小时前
Scala_【2】变量和数据类型
开发语言·后端·scala·intellij-idea