之前有在 Java字符串比较(3种方法)以及对比 C++ 时的注意项 中写过一点关于 equals()与==的比较,但最近的Java考试复习过程中发现有部分情况没涉及到,故重新学习一下


在编写代码的时候我们经常会使用 equals== 来判断两个对象是否相等,那么两者有什么区别呢,主要有以下几点区别:

  1. 首先的区别是,equals 是方法,而 == 是操作符;

  2. 对于基本类型的变量来说(如 shortintlongfloatdouble),只能使用 == ,因为这些基本类型的变量没有 equals 方法。对于基本类型变量的比较,使用 == 比较, 一般比较的是它们的值

  3. 对于引用类型的变量来说(例如 String 类)才有 equals 方法,因为 String 继承了 Object 类, equals 是 Object 类的通用方法。对于该类型对象的比较,默认情况下,也就是没有复写 Object 类的 equals 方法,使用 == 和 equals 比较是一样效果的,都是比较的是它们在内存中的存放地址。但是对于某些类来说,为了满足自身业务需求,可能存在 equals 方法被复写的情况,这时使用 equals 方法比较需要看具体的情况,例如 String 类,使用 equals 方法会比较它们的值

对于上述第三点理解起来可能有点复杂,因为这里 equals 方法比较需要分两种情况来讨论,一种情况是该方法没有被重写,另外一种是该方法被重写。

  • 对于 equals 方法没有被重写的情况。如果类没有重写该方法,那么默认使用的就是 Object 类的方法,以下是 Object 类的 equals 方法:

    1. public boolean equals(Object obj) {
    2. return (this == obj);
    3. }

从源码可以看出,里面使用的就是 == 比较,所以这种情况下比较的就是它们在内存中的存放地址。

  • 对于 equals 方法被重写的情况。以 String 类为例,以下是 String 类中的 equals 方法:

    1. @Override public boolean equals(Object other) {
    2. if (other == this) {
    3. return true;
    4. }
    5. if (other instanceof String) {
    6. String s = (String)other;
    7. int count = this.count;
    8. if (s.count != count) {
    9. return false;
    10. }
    11. if (hashCode() != s.hashCode()) {
    12. return false;
    13. }
    14. char[] value1 = value;
    15. int offset1 = offset;
    16. char[] value2 = s.value;
    17. int offset2 = s.offset;
    18. for (int end = offset1 + count; offset1 < end; ) {
    19. if (value1[offset1] != value2[offset2]) {
    20. return false;
    21. }
    22. offset1++;
    23. offset2++;
    24. }
    25. return true;
    26. } else {
    27. return false;
    28. }
    29. }

从源码可以看出, String 类复写了 equals 方法,当使用 == 比较内存的存放地址不相等时,接下来会比较字符串的内容是否 相等,所以 String 类中的 equals 方法会比较两者的字符串内容是否一样。我们来看看下面的例子:

  1. String a = "Hello World";
  2. String b = new String("Hello World");
  3. String c = b; //引用传递
  4. System.out.println("a == b:" + a == b); //false
  5. System.out.println("b == c:" + b == c); //true
  6. System.out.println("a == c:" + a == c); //false
  7. System.out.println("a.equals(b):" + a.equals(b)); //true
  8. System.out.println("b.equals(c):" + b.equals(c)); //true
  9. System.out.println("a.equals(c):" + a.equals(c)); //true
  10. 最终的打印会是:
  11. a == b:false
  12. b == c:true
  13. a == c:false
  14. a.equals(b):true
  15. b.equals(c):true
  16. a.equals(c):true

因为 String b 通过 new 的方式已经开辟了新的堆内存,而 String a = "Hello World" 是存放在常量池里的,两者在 Java 内存里存在放的位置是不同的,所以 a == b 为 false;而 equals 方法当两者存放的内存地址不同时,会比较两者的值,两者的值都是 "Hello World" ,所以 a.equals(b) 为 true。


另外请思考一下下方代码的运行结果为什么是 True、false

  1. public class Java_epuals {
  2. public static void main(String[] args) {
  3. Integer i2 = 10;
  4. Integer i3 = 10;
  5. System.out.println(i2 == i3); // true
  6. Integer i4 = 128;
  7. Integer i5 = 128;
  8. System.out.println(i4 == i5); // false
  9. }
  10. }

对于 i2i3 的比较,因为变量的定义方法是 i2(i3) = 10 它们的变量会置于常量区,两个变量的内存地址相同。

此时 == 返回 true

那么为什么 i4i5 是返回 false 呢?

这是因为 Java 中 integer 范围取值要在-128到+127 (为什么Integer对象范围(-128-127)之间),而我们赋的值是 128 ,此时变量并不在常量区定义。所以两个变量的内存地址不同,== 返回 false

【Java】equals 和 == 的区别的更多相关文章

  1. java equals和==的区别

    大概说equals和==都比较的是什么: 1. boolean tem = a == b; 首先==比较的肯定是地址,从堆栈的角度说也就是说==比较的是栈上面的内容.因为栈是用来存放地址或是java中 ...

  2. java equals 和 == 的区别

    )1. == 可以用来比较基本类型以及引用类型.在基本类型中 == 比较的是两个变量的值是否相等.在引用类型中,== 比较的是两个对象的内存地址是否相等. )2. equals 只能用来比较引用类型. ...

  3. Java笔记——equals和==的区别

    摔在这里几次,还是记下来吧. 原文:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452156.html -------------- ...

  4. java中equals和==的区别 (转)

    java中equals和==的区别  值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中. ==操作比较的是两个变量的值是否相等,对于引 ...

  5. 【转】Java中equals和==的区别

    [转]Java中equals和==的区别 java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boole ...

  6. java笔记---equals和==的区别

    摔在这里几次,还是记下来吧.原文:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452156.html --------------- ...

  7. java equals和==区别及string类的说明

    一.equals和==的区别 1.1.equals之string字符串的比较 1.1.1.源码如下图 if (this == anObject) {            return true;  ...

  8. Java 中 Equals和==的区别(转)

    另外一篇参考: https://blog.csdn.net/striverli/article/details/52997927 在谈论equals和==的区别前,我们先简单介绍一下JVM中内存分配的 ...

  9. Java中equals和==的区别?为什么重写equals方法后,一定要重写hashCode方法?

    首先明确一点,equals是方法,==是操作符. 1. 如果比较的是基本数据类型: 只讨论==,因为equals是不存在的,因为java中基本数据类型不能调用method的. 2. 如果比较的是引用类 ...

  10. equals和==的区别 (Java基础)

    1. == 是一个运算符.2.Equals则是string对象的方法,可以.(点)出来. 我们比较无非就是这两种 1.基本数据类型比较 2.引用对象比较 1.基本数据类型比较 ==和Equals都比较 ...

随机推荐

  1. 使用C#进行数据库增删改查ADO.NET(三)

    文章代码如下: class Program { static void Main (string[] args) { //连接数据库 string connString = "server= ...

  2. [BD] HBase

    NoSQL数据库 关系型数据库:用表格的行-列来保存数据,OLTP,写入多,行式存储 非关系型数据库:只用来存储数据,业务逻辑由应用程序处理,OLAP,查询多,列式存储 常见NoSQL数据库 Redi ...

  3. [刷题] 203 Remove Linked List Elements

    要求 在链表中删除值为val的所有节点 示例 如 1->2->3->4->5->6->NULL,要求删除值为6的节点 返回1->2->3->4-& ...

  4. 每天一个linux命令(49):at命令   atrm删除作业,由作业号标识。

    atq命令 例如:从现在起三天后的下午四点运行作业at 4pm + 3 days:在July 31上午十点运行作业at 10am July 31:明天上午一点运行作业at 1am tomorrow. ...

  5. xsos:一个在Linux上阅读SOSReport的工具

    xsos:一个在Linux上阅读SOSReport的工具 时间 2019-05-23 14:36:29  51CTO 原文  http://os.51cto.com/art/201905/596889 ...

  6. 马哥Linux SysAdmin学习笔记(一)

    Linux入门 Linux系统管理: 磁盘管理,文件系统管理 RAID基础原理,LVM2 网络管理:TCP/IP协议,Linux网络属性配置 程序包管理:rpm,yum 进程管理:htop,glanc ...

  7. /etc/ssh/sshd_config ssh自动断 cent7

    vim /etc/ssh/sshd_config ClientAliveInterval 60ClientAliveCountMax 8630000 ClientAliveInterval 30Cli ...

  8. BUUCTF(九) [ACTF2020 新生赛]Exec 1

    baidu.com & ls .. baidu.com & ls ../.. baidu.com & ls ../../.. 发现flag 查看 baidu.com & ...

  9. Java 中布尔(boolean)类型占用多少个字节

    为什么要问这个问题,首先在Java中定义的八种基本数据类型中,除了其它七种类型都有明确的内存占用字节数外,就 boolean 类型没有给出具体的占用字节数,因为对虚拟机来说根本就不存在 boolean ...

  10. python 如何让俩个对象相等及如何让俩个对象具有相同的id值