JDK 8 Object 源码详解(完整版带详细注释)
1. 基本结构
/**
* Object类是所有类的根类
* 每个类都直接或间接继承自Object类
* Object类定义了所有对象都具有的基本方法
*/
public class Object {
// Object类没有实例变量
// 所有实例变量都在子类中定义
// 本地方法注册,用于JNI调用
private static native void registerNatives();
// 静态初始化块,加载类时注册本地方法
static {
registerNatives();
}
}
2. 构造函数
/**
* 默认构造函数
* Object类的构造函数是protected的,这样可以确保
* 只有Object类本身或其子类可以创建Object实例
*/
public Object() {
// 空实现,Object类本身不需要初始化
}
3. 核心方法实现
3.1 getClass方法
/**
* 返回对象的运行时类
* @return 对象的Class对象
*/
public final native Class<?> getClass();
/**
* 说明:
* 1. final修饰:不能被子类重写
* 2. native:由JVM本地实现
* 3. 返回值:Class对象,包含了类的元数据信息
* 4. 用途:反射、类型检查、动态加载等
*/
3.2 hashCode方法
/**
* 返回对象的哈希码值
* @return 对象的哈希码值
*
* 通用约定:
* 1. 在应用程序执行期间,只要对象的equals()方法比较中所用的信息没有被修改,
* 同一个对象多次调用hashCode()方法应该返回相同的值
* 2. 如果两个对象根据equals()方法比较是相等的,那么调用这两个对象的hashCode()方法必须产生相同的整数结果
* 3. 如果两个对象根据equals()方法比较是不相等的,那么调用这两个对象的hashCode()方法不要求产生不同的结果
* 但是程序员应该知道,为不相等的对象产生不同的哈希码可以提高哈希表的性能
*/
public native int hashCode();
/**
* 说明:
* 1. native:由JVM本地实现,通常是基于对象的内存地址计算
* 2. 设计原则:相等的对象必须有相同的哈希码
* 3. 性能考虑:哈希码应该快速计算且分布均匀
*/
3.3 equals方法
/**
* 指示其他某个对象是否与此对象"相等"
* @param obj 要与之比较的对象
* @return 如果两个对象相等返回true,否则返回false
*
* equals()方法实现等价关系:
* 1. 自反性:对于任何非null的引用值x,x.equals(x)应该返回true
* 2. 对称性:对于任何非null的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)应该返回true
* 3. 传递性:对于任何非null的引用值x、y和z,如果x.equals(y)返回true,并且y.equals(z)返回true,
* 那么x.equals(z)应该返回true
* 4. 一致性:对于任何非null的引用值x和y,多次调用x.equals(y)应该始终返回true或始终返回false
* 5. 对于任何非null的引用值x,x.equals(null)应该返回false
*/
public boolean equals(Object obj) {
// 默认实现:比较对象引用是否相同
return (this == obj);
}
/**
* 重写equals()方法的模板:
*/
public boolean equalsTemplate(Object obj) {
// 1. 检查是否为同一个对象
if (this == obj)
return true;
// 2. 检查是否为null
if (obj == null)
return false;
// 3. 检查类型是否相同
if (getClass() != obj.getClass())
return false;
// 4. 类型转换
MyClass other = (MyClass) obj;
// 5. 比较关键字段
// return field1 == other.field1 && Objects.equals(field2, other.field2);
return true;
}
3.4 clone方法
/**
* 创建并返回此对象的一个副本
* @return 此实例的一个副本
* @throws CloneNotSupportedException 如果对象的类不支持Cloneable接口
*
* 注意事项:
* 1. x.clone() != x 应该为true
* 2. x.clone().getClass() == x.getClass() 应该为true
* 3. x.clone().equals(x) 应该为true(但这不是绝对要求)
*
* 实现方式:
* 1. 浅拷贝:只复制对象本身,不复制引用的对象
* 2. 深拷贝:递归复制对象及其引用的所有对象
*/
protected native Object clone() throws CloneNotSupportedException;
/**
* 克隆方法的使用示例:
*/
public class MyCloneableClass implements Cloneable {
private int value;
private String name;
@Override
protected Object clone() throws CloneNotSupportedException {
// 调用父类的clone方法
return super.clone();
}
}
3.5 toString方法
/**
* 返回该对象的字符串表示
* @return 对象的字符串表示
*
* 建议:
* 1. 所有子类都应该重写此方法
* 2. 返回的字符串应该简洁且信息丰富
* 3. 格式应该是:类名@哈希码的十六进制表示
*/
public String toString() {
// 默认实现:类名@哈希码的十六进制表示
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
/**
* 重写toString()方法的模板:
*/
public String toStringTemplate() {
return "ClassName[field1=" + field1 + ", field2=" + field2 + "]";
}
3.6 wait方法
/**
* 导致当前线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法
* @throws IllegalMonitorStateException 如果当前线程不是此对象监视器的所有者
* @throws InterruptedException 如果其他线程中断了当前线程
*/
public final native void wait(long timeout) throws InterruptedException;
/**
* 导致当前线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法
* @throws IllegalMonitorStateException 如果当前线程不是此对象监视器的所有者
* @throws InterruptedException 如果其他线程中断了当前线程
*/
public final void wait() throws InterruptedException {
// 无超时时间的等待,调用带参数的wait方法
wait(0);
}
/**
* 导致当前线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法
* @param timeout 等待的最长时间(毫秒)
* @param nanos 额外的纳秒时间(0-999999)
* @throws IllegalMonitorStateException 如果当前线程不是此对象监视器的所有者
* @throws InterruptedException 如果其他线程中断了当前线程
* @throws IllegalArgumentException 如果超时值为负数
*/
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
timeout++;
}
wait(timeout);
}
3.7 notify和notifyAll方法
/**
* 唤醒在此对象监视器上等待的单个线程
* @throws IllegalMonitorStateException 如果当前线程不是此对象监视器的所有者
*/
public final native void notify();
/**
* 唤醒在此对象监视器上等待的所有线程
* @throws IllegalMonitorStateException 如果当前线程不是此对象监视器的所有者
*/
public final native void notifyAll();
3.8 finalize方法
/**
* 当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法
* @throws Throwable 此方法抛出的任何异常都会被忽略
*
* 注意:
* 1. JDK 9开始标记为deprecated
* 2. 不保证finalize()方法会被调用
* 3. finalize()方法可能会延迟对象的回收
* 4. 建议使用try-with-resources或显式清理方法替代
*/
protected void finalize() throws Throwable {
// 默认实现为空
}
4. 线程同步相关方法详解
4.1 wait方法的工作原理
/**
* wait()方法的使用示例
*/
public class WaitNotifyExample {
private final Object lock = new Object();
private boolean condition = false;
// 等待方法
public void waitForCondition() throws InterruptedException {
synchronized (lock) {
while (!condition) {
// 释放锁并等待
lock.wait();
}
// 重新获得锁后继续执行
}
}
// 通知方法
public void setCondition() {
synchronized (lock) {
condition = true;
// 唤醒等待的线程
lock.notifyAll();
}
}
}
4.2 notify和notifyAll的区别
/**
* notify() vs notifyAll() 的区别:
*
* notify():
* - 只唤醒一个等待线程
* - 适用于生产者-消费者模式中只有一个消费者的情况
* - 可能导致死锁或饥饿问题
*
* notifyAll():
* - 唤醒所有等待线程
* - 适用于多个线程等待同一条件的情况
* - 更安全,但可能有性能开销
*/
public class ProducerConsumerExample {
private final Object lock = new Object();
private final Queue<String> queue = new LinkedList<>();
private final int MAX_SIZE = 10;
// 生产者方法
public void produce(String item) throws InterruptedException {
synchronized (lock) {
while (queue.size() == MAX_SIZE) {
// 队列满时等待
lock.wait();
}
queue.offer(item);
// 生产后通知消费者
lock.notifyAll(); // 使用notifyAll()更安全
}
}
// 消费者方法
public String consume() throws InterruptedException {
synchronized (lock) {
while (queue.isEmpty()) {
// 队列空时等待
lock.wait();
}
String item = queue.poll();
// 消费后通知生产者
lock.notifyAll(); // 使用notifyAll()更安全
return item;
}
}
}
5. Object类的典型应用场景
5.1 作为基类
/**
* 所有类都隐式继承Object类
*/
public class MyClass {
// 自动继承Object的所有方法
// 可以重写Object的方法
@Override
public String toString() {
return "MyClass instance";
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
MyClass myClass = (MyClass) obj;
return true;
}
@Override
public int hashCode() {
return Objects.hash(); // 或者返回固定值
}
}
5.2 反射中的使用
/**
* 通过Object类的getClass()方法进行反射操作
*/
public class ReflectionExample {
public static void demonstrateReflection() {
String str = "Hello";
Class<?> clazz = str.getClass();
// 获取类名
System.out.println("Class name: " + clazz.getName());
// 获取方法
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
System.out.println("Method: " + method.getName());
}
// 获取字段
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
System.out.println("Field: " + field.getName());
}
}
}
5.3 泛型中的使用
/**
* 在泛型中使用Object作为类型参数的上界
*/
public class GenericExample<T extends Object> {
private T value;
public GenericExample(T value) {
this.value = value;
}
public T getValue() {
return value;
}
@Override
public String toString() {
return "GenericExample{value=" + value + "}";
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
GenericExample<?> that = (GenericExample<?>) obj;
return Objects.equals(value, that.value);
}
@Override
public int hashCode() {
return Objects.hash(value);
}
}
6. 最佳实践和注意事项
6.1 equals和hashCode的配对实现
/**
* 正确实现equals和hashCode的示例
*/
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
// 1. 检查是否为同一个对象
if (this == obj) return true;
// 2. 检查是否为null
if (obj == null) return false;
// 3. 检查类型
if (getClass() != obj.getClass()) return false;
// 4. 类型转换和字段比较
Person person = (Person) obj;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
// 使用Objects.hash()方法计算哈希码
return Objects.hash(name, age);
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
6.2 clone方法的正确实现
/**
* 深拷贝的clone实现示例
*/
public class DeepCopyExample implements Cloneable {
private String name;
private List<String> hobbies;
public DeepCopyExample(String name, List<String> hobbies) {
this.name = name;
// 深拷贝:创建新的List
this.hobbies = new ArrayList<>(hobbies);
}
@Override
protected Object clone() throws CloneNotSupportedException {
// 调用父类的clone方法
DeepCopyExample cloned = (DeepCopyExample) super.clone();
// 深拷贝:创建新的List
cloned.hobbies = new ArrayList<>(this.hobbies);
return cloned;
}
}
6.3 wait/notify的正确使用模式
/**
* wait/notify的标准使用模式
*/
public class StandardWaitNotifyPattern {
private final Object lock = new Object();
private boolean condition = false;
public void waitForCondition() throws InterruptedException {
synchronized (lock) {
// 使用while循环检查条件(防止虚假唤醒)
while (!condition) {
lock.wait();
}
// 条件满足后的处理逻辑
}
}
public void setConditionAndNotify() {
synchronized (lock) {
condition = true;
// 使用notifyAll()而不是notify()
lock.notifyAll();
}
}
}
7. 总结
7.1 Object类的核心作用
- 类型层次结构的根:所有类都直接或间接继承自Object
- 提供基本方法:定义了所有对象都应该具备的基本操作
- 支持反射机制:通过getClass()方法支持运行时类型检查
- 支持线程同步:提供wait/notify机制支持线程间通信
7.2 方法分类
方法类别 | 方法 | 特点 |
---|---|---|
基本信息 | getClass(), hashCode(), toString() | 获取对象基本信息 |
对象比较 | equals() | 对象相等性判断 |
对象复制 | clone() | 对象拷贝 |
线程同步 | wait(), notify(), notifyAll() | 线程间协调 |
对象清理 | finalize() | 对象销毁前的清理(已废弃) |
7.3 设计原则
- 最小化原则:只提供最基本的、所有对象都需要的方法
- 扩展性原则:通过继承机制允许子类定制行为
- 安全性原则:关键方法使用final修饰防止恶意重写
- 一致性原则:相关方法保持语义一致性(如equals和hashCode)
7.4 现代Java中的变化
- finalize()方法废弃:JDK 9开始标记为deprecated
- 增强的equals():java.util.Objects提供辅助方法
- 更好的克隆支持:推荐使用拷贝构造函数或工厂方法
- 并发工具类:推荐使用java.util.concurrent包替代wait/notify
Object类作为Java语言的基石,理解其设计思想和实现原理对于Java开发者至关重要。它是面向对象编程思想的集中体现,为整个Java生态系统提供了统一的基础。