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博客

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

相关推荐
day3ZY19 分钟前
清理C盘缓存,电脑缓存清理怎么一键删除,操作简单的教程
c语言·开发语言·缓存
学地理的小胖砸31 分钟前
【高分系列卫星简介】
开发语言·数码相机·算法·遥感·地理信息
码农豆豆33 分钟前
4.C++中程序中的命名空间
开发语言·c++
怀九日36 分钟前
C++(学习)2024.9.19
开发语言·c++·学习·重构·对象·
希忘auto39 分钟前
Java之线程篇四
java
蓝黑20201 小时前
Java知识点小结3:内存回收
java·gc
KookeeyLena81 小时前
如何限制任何爬虫爬取网站的图片
开发语言·c++·爬虫
yanyanwenmeng1 小时前
matlab基础
开发语言·算法·matlab
Yz98761 小时前
Hadoop里面MapReduce的序列化与Java序列化比较
java·大数据·jvm·hadoop·分布式·mapreduce·big data
凯哥Java1 小时前
优化批处理流程:自定义BatchProcessorUtils的设计与应用
java·数据库·mysql