== 比较对象引用而非值,故不能判断内容是否相等;应使用重写后的 equals() 方法(配合 hashcode()),或 objects.equals() 安全调用。

Java 中关系运算符(如 ==)不能直接比较两个对象的“值是否相等”,它只比较引用(内存地址)。要比较对象的值是否相等,必须使用 equals() 方法——这不是关系运算符,而是实例方法。
为什么 == 不适合比较对象的值?
-
==对于引用类型,判断的是两个变量是否指向堆中同一个对象。 - 即使两个对象内容完全一样(比如两个
new String("abc")),==仍返回false。 - 仅在极少数情况(如字符串字面量、
Integer.valueOf(-128~127)缓存值)下==可能“碰巧”为true,但这不是语义保证,不可依赖。
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // false → 地址不同
System.out.println(s1.equals(s2)); // true → 内容相同
正确方式:用 equals() 比较对象值
-
Object类定义了public boolean equals(Object obj),默认实现就是return this == obj;。 - 所以未重写的类,
equals()和==效果完全一样。 - JDK 多数包装类(
String,Integer,LocalDate,BigDecimal等)已重写equals(),按业务逻辑比较内容。
✅ 推荐写法:
if (obj1 != null && obj1.equals(obj2)) { ... }
// 或更安全:Objects.equals(obj1, obj2)
Objects.equals(a, b) 会自动处理 null,避免空指针。
自定义类必须重写 equals()(并同步重写 hashCode())
否则 user1.equals(user2) 永远是 false(除非是同一实例)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
重写要点:
- 先判
this == obj(提高效率) - 再判
obj == null - 再用
getClass() != obj.getClass()保证类型一致(不建议用instanceof,破坏对称性) - 强制类型转换后,逐个比较关键业务字段(基本类型用
==,引用类型用Objects.equals())
示例:
@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);
}
⚠️ 忘记重写 hashCode() 会导致对象在 HashMap/HashSet 中行为异常(如 contains() 找不到、重复添加)。
特殊类型注意点
-
浮点数(
float/double):不要用==直接比值,要用误差范围(Math.abs(a - b) )。 -
数组:
==比地址,Arrays.equals(arr1, arr2)才比内容;多维数组用Arrays.deepEquals。 -
枚举(enum):可用
==,因为枚举常量是单例,JVM 保证同一枚举值全局唯一。
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










