Java中的"equals"和"=="的用法及区别

在初学Java时,可能会经常碰到下面的代码:

1 String str1 = new String("hello");
2 String str2 = new String("hello");
3 System.out.println(str1==str2);
4 System.out.println(str1.equals(str2));

为什么第4行和第5行的输出结果不一样?==和equals方法之间的区别是什么?如果在初学Java的时候这个问题不弄清楚,就会导致自己在以后编写代码时出现一些低级的错误。今天就来一起了解一下==和equals方法的区别之处。

一.关系操作符“==”到底比较的是什么?

  下面这个句话是摘自《Java编程思想》一书中的原话:

  “关系操作符生成的是一个boolean结果,它们计算的是操作数的值之间的关系”。

  这句话看似简单,理解起来还是需要细细体会的。说的简单点,==就是用来比较值是否相等。下面先看几个例子:

 1 public class Main {
 2
 3     /**
 4      * @param args
 5      */
 6     public static void main(String[] args) {
 7         // TODO Auto-generated method stub
 8
 9         int n=3;
10         int m=3;
11
12         System.out.println(n==m);
13
14         String str = new String("hello");
15         String str1 = new String("hello");
16         String str2 = new String("hello");
17
18         System.out.println(str1==str2);
19
20         str1 = str;
21         str2 = str;
22         System.out.println(str1==str2);
23     }
24
25 }

  输出结果为:

true
false
true

  n==m结果为true,这个很容易理解,变量n和变量m存储的值都为3,肯定是相等的。而为什么str1和str2两次比较的结果不同?要理解这个其实只需要理解基本数据类型变量和非基本数据类型变量的区别。

  在Java中游8种基本数据类型:

  浮点型:float(4 byte), double(8 byte)

  整型:byte(1 byte), short(2 byte), int(4 byte) , long(8 byte)

  字符型: char(2 byte)

  布尔型: boolean(JVM规范没有明确规定其所占的空间大小,仅规定其只能够取字面值"true"和"false")

  对于这8种基本数据类型的变量,变量直接存储的是“值”,因此在用关系操作符==来进行比较时,比较的就是 “值” 本身。要注意浮点型和整型都是有符号类型的,而char是无符号类型的(char类型取值范围为0~2^16-1).

  也就是说比如:

  int n=3;

  int m=3; 

  变量n和变量m都是直接存储的"3"这个数值,所以用==比较的时候结果是true。

  而对于非基本数据类型的变量,在一些书籍中称作为 引用类型的变量。比如上面的str1就是引用类型的变量,引用类型的变量存储的并不是 “值”本身,而是于其关联的对象在内存中的地址。比如下面这行代码:

  String str1;

  这句话声明了一个引用类型的变量,此时它并没有和任何对象关联。

  而 通过new String("hello")来产生一个对象(也称作为类String的一个实例),并将这个对象和str1进行绑定:

  str1= new String("hello");

  那么str1指向了一个对象(很多地方也把str1称作为对象的引用),此时变量str1中存储的是它指向的对象在内存中的存储地址,并不是“值”本身,也就是说并不是直接存储的字符串"hello"。这里面的引用和C/C++中的指针很类似。

  因此在用==对str1和str2进行第一次比较时,得到的结果是false。因此它们分别指向的是不同的对象,也就是说它们实际存储的内存地址不同。

  而在第二次比较时,都让str1和str2指向了str指向的对象,那么得到的结果毫无疑问是true。

二.equals比较的又是什么?

  equals方法是基类Object中的方法,因此对于所有的继承于Object的类都会有该方法。为了更直观地理解equals方法的作用,直接看Object类中equals方法的实现。

  该类的源码路径为:C:\Program Files\Java\jdk1.6.0_14的src.zip 的java.lang路径下的Object.java(视个人jdk安装路径而定)。

  下面是Object类中equals方法的实现:

  

  很显然,在Object类中,equals方法是用来比较两个对象的引用是否相等,即是否指向同一个对象。

  但是有些朋友又会有疑问了,为什么下面一段代码的输出结果是true?

 1 public class Main {
 2
 3     /**
 4      * @param args
 5      */
 6     public static void main(String[] args) {
 7         // TODO Auto-generated method stub
 8
 9         String str1 = new String("hello");
10         String str2 = new String("hello");
11
12         System.out.println(str1.equals(str2));
13     }
14 }

  要知道究竟,可以看一下String类的equals方法的具体实现,同样在该路径下,String.java为String类的实现。

  下面是String类中equals方法的具体实现:

  可以看出,String类对equals方法进行了重写,用来比较指向的字符串对象所存储的字符串是否相等。

  其他的一些类诸如Double,Date,Integer等,都对equals方法进行了重写用来比较指向的对象所存储的内容是否相等。

  总结来说:

  1)对于==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;

    如果作用于引用类型的变量,则比较的是所指向的对象的地址

  2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量

    如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;

    诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。

转载于:https://www.cnblogs.com/ECJTUACM-873284962/p/7460129.html

【Java学习笔记之二十九】Java中的equals和==的用法及区别相关推荐

  1. 【Java学习笔记之二十六】深入理解Java匿名内部类

    在[Java学习笔记之二十五]初步认知Java内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意 ...

  2. java学习笔记(二十八)——开发一个小项目(VMeeting3.0)

    上篇文章按照较规范的产品需求文档梳理了项目的逻辑,感觉开发起来明晰了很多:挂上一篇文章java学习笔记(二十七)--开发一个小项目(VMeeting2.0)_Biangbangbing的博客-CSDN ...

  3. 【OS学习笔记】二十九 保护模式八:任务切换对应的汇编代码之用户程序代码

    本汇编代码对应以下两篇文章对应的用户程序汇编代码: [OS学习笔记]二十六 保护模式八:任务门-任务切换 [OS学习笔记]二十七 保护模式八:任务切换的方法之----jmp与call的区别以及任务的中 ...

  4. 线性代数学习笔记(二十九)——方程组解的结构(一)

    停更2年多了,做事得有始有终,继续更新... 本篇笔记回顾了线性方程组解的三种情况,并讨论了齐次线性方程组解的结构,并介绍了齐次线性方程组解的相关性质.其中重点讨论了基础解系定义,以及基础解系的求法和 ...

  5. Python学习笔记(一)1.Python中end=和sep=的用法与区别。

    一.Python中end=和sep=的用法与区别: python中常用到的end=和sep=两种参数用法相似,一个是python输出结尾,一个是python输出分割. end: 默认是换行,表示两个字 ...

  6. 【Java学习笔记之二十八】深入了解Java8新特性

    前言: Java 8 已经发布很久了,很多报道表明java 8 是一次重大的版本升级.在Java Code Geeks上已经有很多介绍Java 8新特性的文章,例如Playing with Java ...

  7. Java学习笔记(二):Java程序基础

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://mp.csdn.net/mdeditor/100619398 目录 ...

  8. 【Java学习笔记之二十五】初步认知Java内部类

    可以将一个类的定义放在另一个类的定义内部,这就是内部类. 内部类是一个非常有用的特性但又比较难理解使用的特性(鄙人对内部类也只是略知一二). 第一次见面 内部类我们从外面看是非常容易理解的,无非就是在 ...

  9. JAVA学习笔记(二十)

    对象数组 题目: 定义一个数组,用来储存3个Person对象. public class plas {private String name;private int age;​public plas( ...

最新文章

  1. codeforces #310 div1 C
  2. 商务部数据揭示了零售行业的哪些新趋势?
  3. 作业调度算法--短作业优先 操作系统_处理器管理_编程题
  4. vue通过链接显示服务器上的图片_图片网站该如何做SEO优化?详细讲解图片优化技巧...
  5. html5对属性布尔的值设定,如何在Javascript中设置HTML5必需属性?
  6. android音频杂音问题_如何消除音频中的噪声?用这个简单好用的音频剪辑软件就够了...
  7. HDU TIANKENG’s rice shop(模拟)
  8. 【更新】PDF控件Spire.PDF 3.9.568发布 | 附下载
  9. Sentry安装教程
  10. Java API 帮助文档中英文版下载
  11. EPIC的服务器稳定吗,epic国内有服务器吗(epic服务器在哪)
  12. API文档,已取消到该网页的导航
  13. 万恶的LayoutSubviews
  14. 入侵检测系统(IDS)与入侵防御系统(IPS)的简单理解
  15. 四、Mosquitto 高级应用之用户配置
  16. java 图像梯度检测_opencv学习笔记(六)---图像梯度
  17. 最简单的方式讲明白numpy.reshape()函数
  18. matlab中qr函数 QR分解
  19. 蓝光原版与蓝光Remux格式到底有什么区别?
  20. 6.3 由学得用——《逆袭大学》连载

热门文章

  1. 再见!Python不想再被这么搞了!
  2. 又跌了!7 月程序员工资平均 14357 元 | 原力计划
  3. 手机主宰了你的生活,这不是乔布斯想看到的
  4. 2018 F40中国青年投资人
  5. Git 同一个Git HostName 配置多个sshkey
  6. 牛客网NOIP赛前集训营-普及组(第一场)
  7. 【收藏】银联在线支付商户UPMP接口的使用和说明
  8. HP-UX crontab: you are not authorized to use cron
  9. 【原创】parseInt大改造
  10. 解读:spring-boot logging。记一次Logback在spring-boot中的使用方法