Java中==与equals()的用法及区别总结

 更新时间:2026年05月18日 11:32:01   作者:莫寒清  
在Java编程中==运算符和equals方法是常用来比较对象或基本数据类型的重要工具,这篇文章主要介绍了Java中==与equals()的用法及区别总结的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

1. 一句话总结

  • ==基本类型比值引用类型比地址(判断是否指向堆中同一个对象)。
  • equals():是一个方法。默认实现(Object 类)也是比地址;但 String、包装类等通过重写实现了内容/逻辑相等的比较。

核心金句== 判断“是不是同一个”;equals() 判断“长得像不像”(取决于是否重写)。

2. 核心区别对比表

特性==equals()
本质Java 运算符Object 类的方法
比较内容基本类型比数值,引用类型比内存地址默认比地址,重写后比对象内容
可定制性不可重写,行为固定可以重写,自定义逻辑相等规则
适用范围任何基本类型或对象引用仅限对象(不能用于基本类型)
null 处理null == null 为 truenull.equals(...) 会抛 NPE

3.==的用法

3.1 基本类型比较(比较值)

int a = 10;
int b = 10;
System.out.println(a == b); // true

char c1 = 'A';
char c2 = 'B';
System.out.println(c1 == c2); // false

3.2 引用类型比较(比较地址)

String s1 = new String("Java");
String s2 = new String("Java");
String s3 = s1;

System.out.println(s1 == s2); // false(不同对象)
System.out.println(s1 == s3); // true(同一引用)

4.equals()的用法

4.1 默认行为:Object.equals()等同于==

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

4.2 重写后的行为:比较内容/逻辑相等

String 重写了 equals(),比较字符串内容:

String s1 = new String("Java");
String s2 = new String("Java");

System.out.println(s1.equals(s2)); // true

5. 进阶高频考点(建议必背)

5.1 字符串常量池(String Pool)

面试常考:为什么 a == b 有时是 true,有时是 false?

String a = "abc";
String b = "abc";
String c = new String("abc");

System.out.println(a == b);       // true(常量池同一对象)
System.out.println(a == c);       // false(new 在堆上创建新对象)
System.out.println(a.equals(c));  // true(内容相等)

补充:

String d = c.intern();
System.out.println(a == d); // true(intern 返回常量池引用)

5.2 包装类缓存机制(Integer Cache)

IntegerShortByteCharacterLong(部分范围)存在缓存机制。

Integer x = 127;
Integer y = 127;
Integer m = 128;
Integer n = 128;

System.out.println(x == y);      // true  (缓存 -128~127)
System.out.println(m == n);      // false (超出缓存范围)
System.out.println(m.equals(n)); // true

结论:比较包装类型的值,优先用 equals()(或拆箱成基本类型再比 ==,注意 null 拆箱会 NPE)。

5.3equals()与hashCode()的契约(HashMap/HashSet 面试点)

  • 两个对象如果 equals()true,那么它们的 hashCode() 必须相同
  • HashMap/HashSet 的基本流程:先 hashCode() 定位桶,再 equals() 精确比较。
  • 如果只重写 equals() 不重写 hashCode():可能出现“放得进去、取不出来”或“重复放入”的问题。

6.equals()正确重写规则(契约)

  1. 自反性x.equals(x) 必须为 true
  2. 对称性x.equals(y)truey.equals(x) 也为 true
  3. 传递性x.equals(y)y.equals(z)truex.equals(z) 必须为 true
  4. 一致性:对象状态不变时,多次调用结果一致。
  5. 非空性x.equals(null) 必须为 false

7.instanceof还是getClass()?(加分点)

  • getClass():要求必须同一具体类才相等,更严格,较不易破坏对称性。
  • instanceof:允许子类参与比较,更灵活,但继承体系下容易破坏对称性/传递性。

8.null安全:避免 NPE 的写法(实用)

8.1 容易出错

String s = null;
System.out.println(s.equals("a")); // NPE

8.2 推荐写法

String s = null;
System.out.println("a".equals(s)); // false

或:

System.out.println(java.util.Objects.equals(s, "a")); // false(null-safe)

9. 一个规范的重写示例(可背模板)

import java.util.Objects;

public class Person {
    private final String name;
    private final int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

10. 什么时候用==?什么时候用equals()?(面试收尾)

  • 基本类型:用 ==
  • 判断两个引用是否指向同一对象:用 ==
  • 判断对象内容(业务逻辑相等):用 equals()(并确保类正确重写 equals/hashCode)。
  • 比较 enum:推荐使用 ==(枚举天然单例,且语义明确)。

11. 常见追问补充(可选)

  1. StringBuilder / StringBufferequals():没有重写,仍是地址比较;要比内容用 toString()
  2. 数组的 equals():数组没有重写 equals(),比较地址;比内容用 Arrays.equals() / Arrays.deepEquals()
  3. 浮点数比较== 可能因精度误差不可靠,业务上常用误差范围(epsilon)比较。

总结 

到此这篇关于Java中==与equals()的用法及区别总结的文章就介绍到这了,更多相关Java ==与equals()区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java读取数据库表的示例代码

    Java读取数据库表的示例代码

    这篇文章主要介绍了Java读取数据库表,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-05-05
  • JAVA实现双向链表的增删功能的方法

    JAVA实现双向链表的增删功能的方法

    本篇文章主要介绍了JAVA实现双向链表的增删功能的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • spring boot整合mybatis+mybatis-plus的示例代码

    spring boot整合mybatis+mybatis-plus的示例代码

    这篇文章主要介绍了spring boot整合mybatis+mybatis-plus的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • IDEA启动Springboot报错:无效的目标发行版:17 的解决办法

    IDEA启动Springboot报错:无效的目标发行版:17 的解决办法

    这篇文章主要给大家介绍了IDEA启动Springboot报错:无效的目标发行版:17 的解决办法,文中通过代码示例和图文讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-02-02
  • 解决springboot的JPA在Mysql8新增记录失败的问题

    解决springboot的JPA在Mysql8新增记录失败的问题

    这篇文章主要介绍了解决springboot的JPA在Mysql8新增记录失败的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • 如何利用Java实现MySQL的数据变化监听

    如何利用Java实现MySQL的数据变化监听

    在高并发和大数据环境下,实时获取 MySQL 数据库的增量变化对数据同步、数据分析、缓存更新等场景至关重要,下面我们就来看看如何通过Java实现MySQL的数据变化监听吧
    2025-02-02
  • java 中链表的定义与使用方法

    java 中链表的定义与使用方法

    这篇文章主要介绍了java 中链表的定义与使用方法的相关资料,需要的朋友可以参考下
    2017-03-03
  • Spring Boot项目中使用OpenAI-Java的示例详解

    Spring Boot项目中使用OpenAI-Java的示例详解

    Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程,这篇文章主要介绍了Spring Boot项目中使用OpenAI-Java的示例详解,需要的朋友可以参考下
    2023-04-04
  • Apache SkyWalking 修复TTL timer 失效bug详解

    Apache SkyWalking 修复TTL timer 失效bug详解

    这篇文章主要为大家介绍了Apache SkyWalking 修复TTL timer 失效bug详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • 解决mapper自动装配识别不了,Could not autowire.No beans of‘UserMapper‘type found

    解决mapper自动装配识别不了,Could not autowire.No beans&

    文章介绍了在使用MyBatisX插件和MybatisPlus自动生成代码后,如何解决Spring Boot项目中自动注入`UserMapper`时报错的问题,主要方法包括在主配置类或启动类上添加`@MapperScan`注解,指定Mapper文件夹所在的包路径,以及在Mapper类上添加`@Repository`注解
    2024-11-11

最新评论