前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入解析==与equals()区别

深入解析==与equals()区别

作者头像
公众号 IT老哥
修改2020-09-21 15:31:51
3200
修改2020-09-21 15:31:51
举报

本文源自 公-众-号 IT老哥 的分享

IT老哥,一个在大厂做高级Java开发的程序员,每天分享技术干货文章

前言

相信大家一定在很多地方多看到过==equals()的区别,也把区别讲的很详细,每次记住了,很快又会变得模糊不清。 这时就需要从原理深入剖析,一招制敌!

认识==的用法

在Java中,==的作用有两个

(1).基础数据类型:比较的是两者的值是否相等,比如int,float,double变量。

代码语言:javascript
复制
public static void main(String[] args) {
  int a = 1;
  int b = 1;
  float x = 3.2f;
  float y = 3.2f;
  System.out.println(a == b); 
  System.out.println(x == y); 
 }

此时结果,两个都为true。

(2).引用数据类型:比较的是两者的地址是否相同,比如Integer等。String是一个特殊的,后面再讨论。

代码语言:javascript
复制
public static void main(String[] args) {
  Integer a = new Integer(1);
  Integer b = new Integer(1);
  Integer c = 1;
  System.out.println(a == b); 
  System.out.println(a == c); 
 }

此时结果,两个都为false。因为使用Integer类,每次都创建了新的对象,所以分配的地址是不同的。但Integer类与int作比较结果如何呢?

代码语言:javascript
复制
public static void main(String[] args) {
  Integer a = new Integer(1);
  Integer b = new Integer(1);
  int c = 1;
  System.out.println(a == b);//false
  System.out.println(c == a);//true
  System.out.println(c == b);//true
 }

输出结果:false,true,true。此时我们不难发现,当包装类与其基本类型进行比较时,会转变为对两者的值的比较。

认识equals()的用法

equals()方法源自Object类,先看一下源码是什么样:

代码语言:javascript
复制
public boolean equals(Object obj) {
        return (this == obj);
    }

看到这里,很快就发现equals()方法和==是相同的,所以在使用基本数据类型和引用对象(包装类除外)比较时,两者不存在区别。

代码语言:javascript
复制
public static void main(String[] args) {
  Integer a = new Integer(1);
  Integer b = new Integer(1);
  int c = 1;
  System.out.println(a.equals(c)); 
  System.out.println(b.equals(c)); 
 }

此时结果为:true,true。当包装类与其基本类型用equals()方法进行比较时,同样比较两者的值,也不存在区别。

不同点

有一点是比较特殊的,在使用equals()方法对包装类和包装类进行比较时,则会不同。

代码语言:javascript
复制
public static void main(String[] args) {
  Integer a = new Integer(1);
  Integer b = new Integer(1);
  System.out.println(a.equals(b));//true
  System.out.println(a == b); //false
 }

输出结果:true,false。包装类和包装类采用equals()方法,也会转变成对值得比较。为什么呢?因为包装类重写了Object类的equals()方法。打开重写后equals()方法的源码:

代码语言:javascript
复制
public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

从这里可以看出,包装类和包装类的比较,就是两者值得比较。

String类中的==和equals()方法

在String中,重写了Object类的equals(),自然逻辑和功能不同了。

String类中的equals()方法

先来看看String类中equals()方法源码:

代码语言:javascript
复制
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;
}

在源码第一个判断中,若两个对象指向地址相同,则返回true。第二个判断中,若字符内容相同,则返回true。其实就是对两者值得比较。

代码语言:javascript
复制
public static void main(String[] args) {
  String a = "Hello";
  String b = "Hello";
  System.out.println(a.equals(b));//true
}

输出结果:true。

String类中的测试

代码语言:javascript
复制
public static void main(String[] args) {
  String a = "Hello";
  String b = "Hello";
  String c = new String("Hello");
  String d = c;
  System.out.println(a == b);//true
  System.out.println(a == c);//false
  System.out.println(c == d);//true

  System.out.println(a.equals(b));//true
  System.out.println(a.equals(c));//true
  System.out.println(c.equals(d));//true
}

为什么出现这样的结果。可以从内存的角度来解释:

3.通过内存来解释

在Java中,一般是把对象放在堆区,对象的引用则放在了栈区

从上图可以看出:

  • 当String a = “Hello”;创建一个引用类型a,指向堆区一个位置,用于保存字符串对象;
  • 当String b = “Hello”;java会到它的常量池中"hello"是不是在常量池中已存在。如果已经存在则返回这个常量池中的"hello"的地址(在java中叫引用)给变量b;
  • String c= new String(“hello world”); 会在堆区再次存放一个字符串对象;
  • String d = c;当中d和c是相同的引用,指向同一个地址。

所以根据此可以判断以上输出结果:

云服务器云硬盘数据库(包括MySQL、Redis、MongoDB、SQL Server),CDN流量包,短信流量包,cos资源包,消息队列ckafka,点播资源包,实时音视频套餐,网站管家(WAF),大禹BGP高防(包含高防包及高防IP),云解析SSL证书,手游安全MTP移动应用安全云直播等等。

代码语言:javascript
复制
//true 指向同一个地址
System.out.println(a == b);  

//false 指向不同地址  
System.out.println\(a == c\);

//true 指向同一个地址
System.out.println\(c == d\);

//true 地址指向的内容相同  
System.out.println\(a.equals\(b\)\);

//true 地址指向的内容相同  
System.out.println\(a.equals©\);

//true 地址指向的内容相同
System.out.println\(c.equals\(d\)\);
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-08-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT老哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 本文源自 公-众-号 IT老哥 的分享
  • 前言
  • 认识==的用法
  • 认识equals()的用法
  • 不同点
  • String类中的==和equals()方法
    • String类中的equals()方法
      • String类中的测试
        • 3.通过内存来解释
        相关产品与服务
        实时音视频
        实时音视频(Tencent RTC)基于腾讯21年来在网络与音视频技术上的深度积累,以多人音视频通话和低延时互动直播两大场景化方案,通过腾讯云服务向开发者开放,致力于帮助开发者快速搭建低成本、低延时、高品质的音视频互动解决方案。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档