==和equals的区别

一、核心定义:== 对比 "地址",equals() 对比 "内容"

先记住最核心的一句话:

  • ==:是运算符 ,作用是比较内存地址 (引用类型)或数值本身(基本类型);
  • equals():是方法 ,默认和==一样比地址,但可以被重写(如 String、Integer),重写后用来比较对象的内容 / 数值

二、分场景详细说明

1. 对比基本数据类型(int、double、char 等)
  • == :可以直接用,比较的是数值本身 (基本类型没有地址,也没有equals()方法);
  • equals():基本类型无法调用,会编译报错。
java 复制代码
int a = 100;
int b = 100;
System.out.println(a == b); // true(比较数值)
// System.out.println(a.equals(b)); // 编译报错:基本类型没有equals方法
2. 对比引用数据类型(Object、String、Integer、自定义类等)

这里分两种情况:未重写equals()已重写equals()

情况 1:未重写equals()(如默认的 Object 类、自定义类)

此时equals()==效果完全一样,都是比较对象的内存地址

java 复制代码
// 自定义一个未重写equals的类
class Person {
    String name;
    public Person(String name) {
        this.name = name;
    }
}

public class Test {
    public static void main(String[] args) {
        Person p1 = new Person("张三");
        Person p2 = new Person("张三");
        Person p3 = p1; // p3和p1指向同一个对象

        // == 比较地址:p1和p2是不同对象,地址不同;p1和p3地址相同
        System.out.println(p1 == p2); // false
        System.out.println(p1 == p3); // true

        // equals() 未重写,默认比地址,结果和==一致
        System.out.println(p1.equals(p2)); // false
        System.out.println(p1.equals(p3)); // true
    }
}
情况 2:已重写equals()(如 String、Integer、Date 等系统类)

此时==仍比较地址equals()被重写为比较对象的内容 / 数值(这也是我们常用的场景)。

例子 1:String 类(最典型)

java 复制代码
String s1 = new String("Java");
String s2 = new String("Java");
String s3 = s1;

// == 比较地址:s1和s2是new出来的不同对象,地址不同
System.out.println(s1 == s2); // false
System.out.println(s1 == s3); // true

// equals() 重写后比较内容:s1和s2内容都是"Java",返回true
System.out.println(s1.equals(s2)); // true

例子 2:Integer 类(对应 128 陷阱)

java 复制代码
Integer i1 = 200;
Integer i2 = 200;

// == 比较地址:200超出缓存范围,i1和i2是不同对象,返回false
System.out.println(i1 == i2); // false

// equals() 重写后比较数值:200=200,返回true
System.out.println(i1.equals(i2)); // true

三、关键补充:为什么 String 还有 "特殊情况"?

你可能见过这样的代码,容易混淆,这里顺便说明:

java 复制代码
String s1 = "Java";
String s2 = "Java";
System.out.println(s1 == s2); // true

这不是==的规则变了,而是 String 的常量池机制 :直接用""创建的字符串会存入常量池,相同内容的字符串只会存一份,所以 s1 和 s2 指向同一个地址。但只要用new String()创建,就会生成新对象,地址不同。

四、如何正确选择?

场景 == equals()
基本类型对比数值 ✅ 必须用 ❌ 不能用
引用类型对比 "是否是同一个对象" ✅ 可以用 ❌ 不推荐(除非确认未重写)
引用类型对比 "内容 / 数值是否相等" ❌ 绝对不要用 ✅ 必须用

总结

  1. ==的核心:基本类型比数值,引用类型比内存地址;
  2. equals()的核心:默认比地址,被重写后(如 String/Integer)比内容;
  3. 实战原则 :对比数值 / 内容用equals(),对比是否是同一个对象用==,基本类型只能用==
相关推荐
MY_TEUCK7 小时前
【Java 后端】SpringBoot 登录认证与会话跟踪实战(JWT + Filter/Interceptor)
java·开发语言·spring boot
今天长肉了吗7 小时前
银行风控项目踩坑实录:指标跑了6小时,风险评分全挂了
java
QQ2422199797 小时前
基于python+微信小程序的家教管理系统_mh3j9
开发语言·python·微信小程序
随读手机8 小时前
多式联运信息交互平台完整方案(2026版)
java·ai·eclipse·云计算·区块链
沐知全栈开发8 小时前
JavaScript 条件语句
开发语言
RSTJ_16258 小时前
PYTHON+AI LLM DAY THREETY-SEVEN
开发语言·人工智能·python
清水白石0088 小时前
《Python性能深潜:从对象分配开销到“小对象风暴”的破解之道(含实战与最佳实践)》
开发语言·python
Je1lyfish8 小时前
CMU15-445 (2025 Fall/2026 Spring) Project#3 - QueryExecution
linux·c语言·开发语言·数据结构·数据库·c++·算法
许彰午8 小时前
03-二叉树——从递归遍历到非递归实现
java·算法
nj01288 小时前
Spring 循环依赖详解:三级缓存、早期引用、AOP 代理与懒加载
java·spring·缓存