【JAVA基础面经】== 和 equals() 的区别

文章目录

  • 前言
  • ==
  • equals()
    • equals()默认与==一致
    • [重写 equals()用于比较内容](#重写 equals()用于比较内容)
    • [自定义类重写 equals()](#自定义类重写 equals())
  • [== 与 equals() 的陷阱代码](#== 与 equals() 的陷阱代码)

前言

== 比地址;equals 默认比地址,重写后比内容

 == 用于基本类型时比较数值,用于引用类型时比较内存地址(是否为同一对象);equals() 是 Object 类的方法,默认行为与 == 相同(比较地址),但可被重写以实现内容比较(如 String、Integer 等)。

==

  1. 对于基本数据类型,只能用 ==,此时比较数值
java 复制代码
int a = 10;
int b = 10;
System.out.println(a == b);  // true,值相等

double d1 = 3.14;
double d2 = 3.14;
System.out.println(d1 == d2); // true
  1. 对于引用类型(对象),== 比较引用地址,s1 和 s2 是两个不同的对象,内存地址不同,因此 == 返回 false。
java 复制代码
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2);   // false,因为 s1 和 s2 指向堆中不同的 String 对象

equals()

equals()默认与==一致

 Object 类中的 equals() 方法默认实现就是使用 ==,所以,如果自定义类不重写 equals(),那么 equals() 的行为与 == 完全一致(比较地址)

java 复制代码
// Object.java 中的默认实现
public boolean equals(Object obj) {
    return (this == obj);
}

重写 equals()用于比较内容

 但很多 Java 核心类(如 String、Integer、Date 等)都重写了 equals(),用于比较对象内部的"内容"是否相等。

java 复制代码
String s1 = "hello";      // 常量池
String s2 = "hello";      // 复用常量池中的对象
System.out.println(s1 == s2);   // true,因为地址相同(特殊优化)

String s3 = new String("hello");
System.out.println(s1 == s3);   // false,new 强制创建新对象

System.out.println(s1.equals(s2));  // true,因为 String 重写了 equals,比较字符序列

 字符串字面量(String s = "hello")会放入字符串常量池,相同内容的字面量指向同一对象。

自定义类重写 equals()

 如果自定义类需要内容比较(例如两个 Person 对象,姓名和年龄相同就视为相等),必须重写 equals()。同时一般也要重写 hashCode(),保证一致。

java 复制代码
public class Person {
    private String name;
    private int age;

    // 构造方法、getter/setter 省略

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

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

== 与 equals() 的陷阱代码

java 复制代码
Integer a = 100;
Integer b = 100;
System.out.println(a == b);  // true,因为 Integer 缓存了 -128~127

Integer c = 200;
Integer d = 200;
System.out.println(c == d);  // false,超出缓存范围,创建了新对象
java 复制代码
String s1 = "hello";      // 常量池
String s2 = "hello";      // 复用常量池中的对象
System.out.println(s1 == s2);   // true,因为地址相同(特殊优化)

String s3 = new String("hello");
System.out.println(s1 == s3);   // false,new 强制创建新对象
相关推荐
GIS数据转换器1 小时前
地下空间综合管廊运营管理平台
大数据·开发语言·人工智能·经验分享·perl
猿究院_夏燊6 小时前
Spring Bean 生命周期
java·后端·spring
Wang's Blog7 小时前
Java 项目实战: 交友项目:登录链路回顾与今日任务地图
java·开发语言·状态模式·交友
信誓旦旦的程序猿7 小时前
【Python量化实战宝典 #08】可转债与债券接口手册:转股价·溢价率·纯债价值(Python 可跑)
java·python·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
砚底藏山河7 小时前
python量化:行情数据回溯
java·开发语言·python·金融·maven
今年下半年7 小时前
AI智能体项目实战记录(02):初始化 Python 项目
开发语言·人工智能·python·fastapi
Jlzn88887 小时前
华东电芯分选通道数怎么配才不堵线
java·人工智能·架构·自动化·制造
Williamtym7 小时前
PickGo Lab实践:用浏览器、Python和MCP串起机器人搬运仿真
开发语言·python·机器人
香吧香8 小时前
GRPC连接机制---长连接分析
java·网络与传输协议
DongQiShanRen8 小时前
六根硬件映射(四):归属澄清、两处不一致与卷十一总表
开发语言·人工智能·算法·rust·哈希算法·集成学习