object类是所有java类的根父类,每个类都直接或间接继承它;其核心方法如tostring()、equals()与hashcode()等共同支撑对象行为、集合操作、调试日志及多线程协作等基础能力。

Object 类是所有 Java 类的根父类,每个类都直接或间接继承它。它的方法不是“可有可无”的工具,而是支撑对象行为、集合操作、调试日志、多线程协作等基础能力的骨架。理解它们,关键不在背签名,而在看清每个方法解决什么问题、不重写会怎样、重写时踩哪些坑。
toString():让对象“开口说话”
默认返回类似 Person@1a2b3c4d 的字符串,只包含类名和哈希码十六进制值,对人毫无意义。真正用起来,它决定你在 System.out.println(person)、日志打印、IDE 调试窗口里看到什么。
- 重写时聚焦核心字段,比如姓名、ID、状态,避免堆砌全部属性或泄露密码、token 等敏感信息
- 格式保持稳定,不要在不同版本间随意增减括号或分隔符,否则日志解析可能出错
- 集合(如
ArrayList)调用toString()时,会逐个调用元素的toString(),所以自定义类不重写,整条列表输出就全是 @xxxx
equals() 和 hashCode():一对必须“同步行动”的搭档
equals() 默认用 == 比地址,这在绝大多数业务场景下毫无价值——你关心的是“两个订单是否订单号+金额相同”,不是“是不是同一个内存块”。但一旦重写 equals(),hashCode() 就绝不能放着不管。
- 违反规则的典型后果:
Person对象放进HashSet后找不到,HashMap里get()返回null——因为哈希桶定位错了 - 重写
equals()必须检查 null、类型一致(用getClass()而非instanceof,防止子类比较破坏对称性)、再逐字段比较;推荐用Objects.equals(a, b)处理可能为 null 的字段 -
hashCode()推荐直接用Objects.hash(field1, field2, ...),它已处理 null 和散列分布,比手写位运算更安全可靠
getClass() 和 clone():一个锁死,一个谨慎开启
getClass() 是 final 方法,谁都不能重写。它返回运行时真实类型,比 instanceof 更严格——比如代理对象、CGLIB 增强类,getClass() 返回代理类,而 instanceof 可能返回 true 给原始接口。
- 常用于需要精确类型判断的场景,比如通用序列化、反射创建实例、权限校验中的类型白名单
-
clone()是受保护的 native 方法,默认抛CloneNotSupportedException;想用必须实现Cloneable接口,并重写方法 - 注意它是浅拷贝:若对象含引用类型字段(如
List、自定义对象),克隆后双方仍共享同一份底层数据。真要深拷贝,得手动递归克隆,或改用构造器/Builder 模式更清晰
wait()/notify()/notifyAll():线程通信的底层开关
这三个方法不用于日常业务逻辑编码,而是构建高级并发工具(如 BlockingQueue、锁、信号量)的基石。它们只能在同步块(synchronized)中调用,否则抛 IllegalMonitorStateException。
-
wait()让当前线程释放锁并进入等待队列;notify()唤醒一个等待线程;notifyAll()唤醒全部——实际开发中优先选notifyAll(),避免虚假唤醒导致死锁 - 永远配合 while 循环使用条件判断,而不是 if:因为唤醒后条件未必成立,需重新检验
- 现代 Java 更推荐用
java.util.concurrent包下的高级工具(如Condition、CountDownLatch),语义更明确,不易出错










