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

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

相关推荐
tERS ERTS20 小时前
头歌答案--爬虫实战
java·前端·爬虫
Fate_I_C20 小时前
Kotlin函数一
android·开发语言·kotlin
Eiceblue20 小时前
C# 实现 XLS 与 XLSX 格式双向互转(无需依赖 Office)
开发语言·c#·visual studio
识君啊20 小时前
中小厂数据库事务高频面试题
java·数据库·mysql·隔离级别·数据库事务·acid
云南瑞达工程材料有限公司20 小时前
云南生态袋;云南园林生态袋;昆明河道治理生态袋;边坡生态袋
面试
少许极端20 小时前
算法奇妙屋(四十八)-单调栈
java·算法·单调栈
学习使我健康20 小时前
Android 本地音乐播放(读取系统媒体库 + MediaPlayer)
java·android-studio
水木流年追梦20 小时前
CodeTop Top 300 热门题目2-最长回文子串
开发语言·人工智能·python·算法·leetcode
我不是懒洋洋21 小时前
网络通了但很慢:手写一个TCP连接耗时诊断工具
c语言·经验分享
良木生香21 小时前
【C++初阶】:STL——String从入门到应用完全指南(3)
c语言·开发语言·数据结构·c++·算法