17370845950

在Java里==和equals有什么区别_Java基础比较规则说明
==比较值或地址取决于类型:基本类型比值,引用类型比地址;equals()默认同==,重写后比内容,自定义类需同时重写hashCode()以满足集合要求。

== 比较的是值还是地址,完全看变量类型

基本数据类型(intcharboolean 等)用 ==,比的就是数值本身:int a = 5; int b = 5; a == btrue。但只要换成引用类型(比如 StringCustomer),== 就只认内存地址:哪怕两个 new String("hello") 内容一模一样,== 也返回 false,因为它们是堆里两块不同的内存。

容易踩的坑:

  • 误把字符串字面量和 new String() 当成一回事:"abc" == new String("abc")false,但 "abc" == "abc"true(字符串常量池复用)
  • 对自定义类对象直接用 == 判断“内容是否相同”,结果永远是 false(除非真指向同一实例)

equals() 默认行为和 String 等类的重写差异

equals()Object 类的方法,原始实现就是 return (this == obj) —— 和 == 完全等价。真正让它“有用”的,是像 StringIntegerDate 这些类主动重写了它,改成逐字符/逐字段比较内容。

实操建议:

  • 判断字符串内容是否一致,必须用 .equals(),别信 ==
  • 调用 equals() 前,先确认目标类是否重写了它;没重写的自定义类,equals()== 效果一样
  • 永远避免 obj.equals(null),会抛 NullPointerException;更安全写法是 Objects.equals(a, b)

自定义类想用 equals() 比内容?重写规则不能漏

如果你写了个 Person 类,希望两个 Person 对象在 nameage 相同时就判定相等,就必须重写 equals() 方法。但只改 equals() 不够 —— 规范要求:只要重写了 equals(),就必须同步重写 hashCode(),否则放进 HashMapHashSet 会出问题(比如找不到已存入的对象)。

关键点:

  • equals() 重写要满足:自反性、对称性、传递性、一致性、对 null 返回 false
  • 推荐用 Objects.equals(field1, other.field1) 处理可能为 null 的字段,省去判空
  • IDE(如 IntelliJ)可一键生成合规的 equals()hashCode(),别手写

什么时候该用 ==,什么时候非用 equals() 不可

简单说:== 适合判断“是不是同一个东西”,equals() 适合判断“内容是不是一样”。比如检查某个配置对象是否是单例实例,用 ==;检查用户输入的密码和数据库存的密码是否一致,必须用 .equals()

性能提示:

  • == 是 CPU 指令级比较,极快;equals() 是方法调用+逻辑判断,慢一点,但该用还得用
  • 字符串比较时,== 可作为快速失败检查(先看地址是否相同),再进 equals() 做内容比对,这是 String.equals() 源码里的标准写法
  • 包装类(如 Integer)有缓存机制:Integer a = 127; Integer b = 127; a == btrue,但 a = 128; b = 128 就是 false —— 别依赖这个,一律用 equals()

最易被忽略的一点:equals() 的语义是开发者定义的,不是语言强制的。你重写它,就意味着告诉所有调用方:“从此以后,这两个对象相等的标准,以我的实现为准”。一旦定义了,就要守规矩 —— 特别是 ha

shCode() 必须配套,否则集合类行为不可预测。