Java Object 类笔记

在 Java 的世界里,Object 类是一切类的始祖。理解它的核心方法,掌握 String 及其相关类的特性,是每一个 Java 开发者从入门到精通的必经之路。本文将系统地梳理 Object 类的 11 个核心方法,深入探讨 equalshashCode 的约定,并全面对比 StringStringBufferStringBuilder 的区别。

一、Object 类有哪些核心方法?

Java Object 类是所有类的超类,默认提供 11 个核心方法,涵盖了对象比较、哈希、字符串表示、线程同步等方面。

1. equals(Object obj)

  • 作用:比较两个对象是否相等。

  • 说明 :默认实现比较内存地址(与 == 相同)。实际开发中通常需要重写,按对象的内容(如字段值)判断相等性。

2. hashCode()

  • 作用:返回对象的哈希码值。

  • 说明 :与 equals 配套使用。若两个对象 equals 返回 true,则 hashCode 必须相等;若 hashCode 不等,则 equals 必为 false。如果只重写 equals 不重写 hashCode,会导致对象在 HashMapHashSet 等集合中无法正确存储。

3. toString()

  • 作用:返回对象的字符串表示。

  • 说明 :默认格式为"类名 + @ + 对象的十六进制哈希码"(如 User@1b6d3586),可读性差。通常重写为返回对象的具体信息,便于日志打印和调试。

4. getClass()

  • 作用:返回对象运行时的实际类对象。

  • 说明final 方法,不可重写。常用于反射,获取类的名称、方法、字段等信息,也可用于运行时类型检查。

5. clone()

  • 作用:创建并返回对象的一个副本。

  • 说明 :用于对象的浅拷贝。使用 clone 需要实现 Cloneable 接口,否则抛出 CloneNotSupportedException

6. notify()

  • 作用:随机唤醒一个等待当前对象锁的线程。

  • 说明:必须在同步块中使用。

7. notifyAll()

  • 作用:唤醒所有等待当前对象锁的线程。

  • 说明:必须在同步块中使用。

8. wait()

  • 作用 :让当前线程释放对象锁并进入等待状态,直到被 notify / notifyAll 唤醒。

  • 说明:必须在同步块中调用,通常放在循环中检查等待条件以避免"虚假唤醒"。

9. wait(long timeout)

  • 作用:让当前线程等待指定的毫秒数,超时后自动唤醒。

  • 说明timeout 为 0 表示无限等待。

10. wait(long timeout, int nanos)

  • 作用:提供更精确的时间控制(毫秒 + 纳秒)。

  • 说明:实际超时时间可能受系统调度影响。

11. finalize()

  • 作用:垃圾回收器回收对象前调用,用于执行清理工作。

  • 说明已过时(Deprecated since Java 9) 。执行时机不确定,可能影响性能,甚至导致对象复活。替代方案是使用 try-with-resourcesPhantomReference

二、== 与 equals 有什么区别?

  • ==:对于基本数据类型,比较的是值是否相同;对于引用数据类型,比较的是引用地址是否相同。

  • equals() :不能用于基本数据类型。Object 类中的 equals() 默认使用 == 比较地址。但 String 类重写了 equals() 方法,先比较地址,地址不同则比较内容是否相同。

三、为什么重写 equals 方法时必须重写 hashCode 方法?

在 Java 中,equalshashCode 遵循以下约定:

  • 一致性 :如果 obj1.equals(obj2) 返回 true,那么 obj1.hashCode() 必须等于 obj2.hashCode()

  • 非一致性 :如果两个对象的 hashCode 相同,equals 不一定为 true(哈希冲突)。

如果不重写 hashCode,可能导致对象在哈希集合(如 HashMapHashSet)中无法正确存储。例如,两个 id 相同的 User 对象,equals 返回 true,但 hashCode 不同,会被当成两个不同元素存入集合。

四、Java 中 String 的常用方法有哪些?

  • int length():返回字符串长度。

  • boolean equals(Object obj):比较字符串内容是否相同(区分大小写)。

  • String substring(int beginIndex):从指定索引开始截取子串。

  • String trim():去除字符串首尾空白字符。

  • String replace(char oldChar, char newChar):替换所有指定字符。

  • boolean isEmpty() :判断字符串长度是否为 0(注意:null 调用会报错)。

五、String、StringBuffer、StringBuilder 的区别与联系

1. 可变性

  • String:不可变(Immutable),每次修改都会生成新对象。

  • StringBuilder / StringBuffer:可变(Mutable),可直接修改内容。

2. 线程安全性

  • String:天然线程安全。

  • StringBuilder:非线程安全,适合单线程。

  • StringBuffer :线程安全(方法使用 synchronized),适合多线程。

3. 性能

  • String:性能最低,频繁修改会产生大量临时对象。

  • StringBuilder:性能最高,无同步开销。

  • StringBuffer :性能略低于 StringBuilder,因有同步开销。

4. 使用场景

  • String:字符串内容固定或变化少。

  • StringBuilder:单线程下频繁修改字符串。

  • StringBuffer:多线程下频繁修改字符串。

特性 String StringBuffer StringBuilder
不可变性 不可变 可变 可变
线程安全
性能
适用场景 少量修改 多线程 单线程

六、String 为什么是不可变的?

因为 String 底层使用 final 修饰的 char[] 数组存储字符。数组本身不可变,且 String 类没有提供修改数组内容的方法,所有"修改"操作都会返回新对象。

java 复制代码
Java Object 类深度解析

这种设计带来了线程安全、字符串常量池复用、哈希值缓存等好处。

总结

  • Object 类是 Java 的根类,掌握其核心方法是理解 Java 面向对象的基础。

  • equalshashCode 的约定是哈希集合正确工作的关键。

  • StringStringBuilderStringBuffer 的选择直接影响程序性能和线程安全性。

相关推荐
橘bird2 小时前
LangChain1.2 学习笔记(自用)(未完结)
笔记·python·学习·langchain
小箌2 小时前
JavaWeb & SpringBoot 总结
java·spring boot·后端
智者知已应修善业2 小时前
【任何一个自然数m的立方均可写成m个连续奇数之和】2024-10-17
c语言·数据结构·c++·经验分享·笔记·算法
SimonKing2 小时前
震撼:Qoder 搭载Qwen3.2-Plus模型,5步实现完整的多数据源切换
java·后端·程序员
东离与糖宝2 小时前
Langflow-ai OpenRAG实战:Java+Spring Boot搭建企业级私有知识库(从0到1)
java·人工智能
Rsun045512 小时前
Spring AI 面试题
java·人工智能·spring
小涛不学习2 小时前
Java List 集合深度解析(ArrayList / LinkedList 原理详解)
java·开发语言·windows
郝学胜-神的一滴2 小时前
一序平衡,括号归真:单括号匹配算法的优雅美学
java·前端·数据结构·c++·python·算法