【Java】equals 和 == 的区别

RioTian 2021-06-23 23:37:18
java 区别 博客园 equals


之前有在 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 方法:

     public boolean equals(Object obj) {
    return (this == obj);
    }
    

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

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

     @Override public boolean equals(Object other) {
    if (other == this) {
    return true;
    }
    if (other instanceof String) {
    String s = (String)other;
    int count = this.count;
    if (s.count != count) {
    return false;
    }
    if (hashCode() != s.hashCode()) {
    return false;
    }
    char[] value1 = value;
    int offset1 = offset;
    char[] value2 = s.value;
    int offset2 = s.offset;
    for (int end = offset1 + count; offset1 < end; ) {
    if (value1[offset1] != value2[offset2]) {
    return false;
    }
    offset1++;
    offset2++;
    }
    return true;
    } else {
    return false;
    }
    }
    

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

 String a = "Hello World";
String b = new String("Hello World");
String c = b; //引用传递
System.out.println("a == b:" + a == b); //false
System.out.println("b == c:" + b == c); //true
System.out.println("a == c:" + a == c); //false
System.out.println("a.equals(b):" + a.equals(b)); //true
System.out.println("b.equals(c):" + b.equals(c)); //true
System.out.println("a.equals(c):" + a.equals(c)); //true
最终的打印会是:
a == b:false
b == c:true
a == c:false
a.equals(b):true
b.equals(c):true
a.equals(c):true

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


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

public class Java_epuals {
public static void main(String[] args) {
Integer i2 = 10;
Integer i3 = 10;
System.out.println(i2 == i3); // true
Integer i4 = 128;
Integer i5 = 128;
System.out.println(i4 == i5); // false
}
}

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

此时 == 返回 true

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

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

版权声明
本文为[RioTian]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/RioTian/p/14924959.html

  1. Matrix architecture practice of Boshi fund's Internet open platform based on rocketmq
  2. 字节面试,我这样回答Spring中的循环依赖,拿下20k offer!
  3. Byte interview, I answer the circular dependence in spring like this, and get 20K offer!
  4. oracle 11g查看alert日志方法
  5. How to view alert log in Oracle 11g
  6. 手写Spring Config,最终一战,来瞅瞅撒!
  7. Handwritten spring config, the final battle, come and see!
  8. 用纯 JavaScript 撸一个 MVC 框架
  9. Build an MVC framework with pure JavaScript
  10. 使用springBoot实现服务端XML文件的前端界面读写
  11. Using springboot to read and write the front interface of server XML file
  12. 【Javascript + Vue】实现随机生成迷宫图片
  13. [Javascript + Vue] random generation of maze pictures
  14. 大数据入门:Hadoop伪分布式集群环境搭建教程
  15. Introduction to big data: Hadoop pseudo distributed cluster environment building tutorial
  16. 八股文骚套路之Java基础
  17. commons-collections反序列化利用链分析(3)
  18. Java foundation of eight part wensao routine
  19. Analysis of common collections deserialization utilization chain (3)
  20. dubbogo 社区负责人于雨说
  21. Yu Yu, head of dubbogo community, said
  22. dubbogo 社区负责人于雨说
  23. Yu Yu, head of dubbogo community, said
  24. 设计模式 选自《闻缺陷则喜》此书可免费下载
  25. The design pattern is selected from the book "you are happy when you hear defects", which can be downloaded free of charge
  26. xDAI被选为 Swarm 的侧链解决方案,将百倍降低 Swarm 网络Gas费
  27. L2 - 深入理解Arbitrum
  28. Xdai is selected as the side chain solution of swarm, which will reduce the gas cost of swarm network 100 times
  29. L2 - deep understanding of arbitrum
  30. Java全栈方向学习路线
  31. 设计模式学习04(Java实现)——单例模式
  32. Java full stack learning route
  33. Design pattern learning 04 (Java implementation) - singleton pattern
  34. Mybatis学习01:利用mybatis查询数据库
  35. Mybatis learning 01: using mybatis to query database
  36. Java程序员从零开始学Vue(01)- 前端发展史
  37. Java程序员从零开始学Vue(05)- 基础知识快速补充(html、css、js)
  38. Java programmers learn Vue from scratch
  39. Java programmers learn Vue from scratch (05) - quick supplement of basic knowledge (HTML, CSS, JS)
  40. 【Java并发编程实战14】构建自定义同步工具(Building-Custom-Synchronizers)
  41. [Java Concurrent Programming Practice 14] building custom Synchronizers
  42. 【源码分析】- 在SpringBoot中你会使用REST风格处理请求吗?
  43. [source code analysis] - do you use rest style to process requests in springboot?
  44. 框架篇:见识一下linux高性能网络IO+Reactor模型
  45. Framework: see Linux high performance network IO + reactor model
  46. 基础篇:JAVA.Stream函数,优雅的数据流操作
  47. 基础篇:异步编程不会?我教你啊!CompletableFuture(JDK1.8)
  48. Basic part: Java. Stream function, elegant data stream operation
  49. Basic: asynchronous programming won't? I'll teach you! CompletableFuture(JDK1.8)
  50. 技能篇:sed教程-linux命令
  51. 数据库篇:mysql内置函数
  52. Linux 主要的发行系统版本介绍
  53. 网络篇:朋友面试之https认证加密过程
  54. Skills: sed tutorial - Linux command
  55. Database: built in functions of MySQL
  56. Introduction of Linux main distribution system versions
  57. Network: friends interview: the encryption process of HTTPS authentication
  58. [Linux]经典面试题 - 系统管理 - 备份策略
  59. 解决java socket在传输汉字时出现截断导致乱码的问题
  60. [Linux] classic interview questions system management backup strategy