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

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

相关推荐
小冉在学习8 分钟前
day53 图论章节刷题Part05(并查集理论基础、寻找存在的路径)
java·算法·图论
y5236488 分钟前
Javascript监控元素样式变化
开发语言·javascript·ecmascript
CXDNW28 分钟前
【网络面试篇】HTTP(2)(笔记)——http、https、http1.1、http2.0
网络·笔记·http·面试·https·http2.0
嚣张农民37 分钟前
JavaScript中Promise分别有哪些函数?
前端·javascript·面试
IT技术分享社区38 分钟前
C#实战:使用腾讯云识别服务轻松提取火车票信息
开发语言·c#·云计算·腾讯云·共识算法
极客代码41 分钟前
【Python TensorFlow】入门到精通
开发语言·人工智能·python·深度学习·tensorflow
天行健PLUS1 小时前
【经验分享】六西格玛管理培训适合哪些人参加?
经验分享
疯一样的码农1 小时前
Python 正则表达式(RegEx)
开发语言·python·正则表达式
代码之光_19801 小时前
保障性住房管理:SpringBoot技术优势分析
java·spring boot·后端
ajsbxi1 小时前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet