最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
2 Object Java类体系的根节点
时间:2026-05-29 18:30:01 编辑:袖梨 来源:一聚教程网
作为Java类型体系的根基,Object类承载着所有对象的通用行为规范。深入理解其核心方法,是掌握面向对象编程的关键一步。
Object —— Java 类体系的根节点
一、Object 在 Java 类型体系中的位置
Java采用单根继承模型,所有类都隐式继承自java.lang.Object。无论是否显式声明,编译器都会自动将类与Object建立继承关系。

// 这两种写法完全等价
public class MyClass {}
public class MyClass extends Object {}
Object 的 12 个方法全景图
Object (12个方法)
│
┌──────────────────┼──────────────────┐
│ │ │
本地方法(7) 非final方法(3) final方法(2)
hashCode() equals() getClass()
clone() toString() notify()
registerNatives() finalize() notifyAll()
getClass() + 3个 wait 重载
| 方法 | 修饰符 | 说明 |
|---|---|---|
registerNatives() | private static native | 注册本地方法映射 |
getClass() | public final native | 返回运行时类对象 |
hashCode() | public native | 返回哈希码 |
equals(Object) | public | 判断对象逻辑相等 |
clone() | protected native | 创建并返回拷贝 |
toString() | public | 返回字符串表示 |
notify() | public final native | 唤醒单个等待线程 |
notifyAll() | public final native | 唤醒所有等待线程 |
wait(long) | public final native | 限时等待 |
wait(long, int) | public final | 纳秒级限时等待 |
wait() | public final | 无限等待 |
finalize() | protected | GC 前回调 |
二、registerNatives —— 静态代码块中的秘密
public class Object {
private static native void registerNatives();
static {
registerNatives();
}
}
该静态初始化块在类加载阶段执行,主要完成Java方法与JVM本地函数之间的地址绑定,避免每次调用都进行符号查找。
// OpenJDK 中的 JNI 方法映射表
static JNINativeMethod methods[] = {
{"hashCode", "()I", (void *)&JVM_IHashCode},
{"wait", "(J)V", (void *)&JVM_MonitorWait},
{"notify", "()V", (void *)&JVM_MonitorNotify},
{"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll},
{"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone},
};JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls, methods,
sizeof(methods)/sizeof(methods[0]));
}
三、getClass —— 运行时类型信息
public final native Class> getClass();
该方法返回对象运行时的实际类型信息,而非声明类型,且由于final修饰,子类无法覆盖此方法。
public class GetClassDemo {
public static void main(String[] args) {
Number num = Integer.valueOf(42); Class> clazz = num.getClass();
System.out.println(clazz.getName()); // java.lang.Integer
System.out.println(clazz.getSimpleName()); // Integer
System.out.println(clazz.getSuperclass()); // class java.lang.Number for (java.lang.reflect.Method method : clazz.getDeclaredMethods()) {
System.out.println(" - " + method.getName());
}
}
}
四、hashCode —— 哈希世界的通行证
public native int hashCode();
4.1 哈希码的核心约定
- 一致性:同一对象多次调用结果相同(equals比较字段不变的情况下)
- 等价性:equals返回true则hashCode必须相同
- 不等性:equals返回false时hashCode可以相同(但不同能提升性能)
4.2 OpenJDK 中 hashCode 的生成策略
| 模式 | 算法 | 特点 |
|---|---|---|
| 0 | Park-Miller 随机数 | 默认值 |
| 1 | 基于对象内存地址 + 随机数 | 性能好 |
| 2 | 固定值 1 | 仅用于测试 |
| 3 | 自增序列 | 简单递增 |
| 4 | 内存地址直接转换 | 最直观 |
| 5 | 线程状态 + xorshift | JDK 8 默认 |
4.3 自定义 hashCode 实现示例
public class Person {
private String name;
private int age; public Person(String name, int age) {
this.name = name;
this.age = age;
} @Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
} @Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Person)) return false;
Person other = (Person) obj;
return age == other.age
&& java.util.Objects.equals(name, other.name);
}
}
五、equals —— 逻辑相等的判定
public boolean equals(Object obj) {
return (this == obj);
}
5.1 equals 覆写的五条军规
- 自反性:x.equals(x)必须为true
- 对称性:x.equals(y)与y.equals(x)结果相同
- 传递性:x.equals(y)且y.equals(z)则x.equals(z)
- 一致性:多次调用结果稳定
- 非空性:x.equals(null)返回false
5.2 标准 equals 覆写模板
public class Book {
private String isbn; @Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Book)) return false;
Book other = (Book) obj;
return java.util.Objects.equals(isbn, other.isbn);
}
}
六、clone —— 对象拷贝的底层机制
protected native Object clone() throws CloneNotSupportedException;
6.1 Cloneable 标记接口
该接口作为能力标识,未实现的类调用clone()会抛出异常。
6.2 浅拷贝 vs 深拷贝
static class UserDeep implements Cloneable {
Address address; @Override
protected UserDeep clone() {
UserDeep cloned = (UserDeep) super.clone();
cloned.address = this.address.clone();
return cloned;
}
}
6.3 clone 方法的推荐替代方案
public Order(Order source) {
this.id = source.id;
this.amount = source.amount;
}
七、toString —— 对象的自我描述
public class Product {
@Override
public String toString() {
return String.format("Product{sku='%s', name='%s'}", sku, name);
}
}
八、wait / notify —— 线程间通信的基石
public synchronized void consumeData() {
while (!dataReady) {
wait();
}
}
九、finalize —— 不推荐的资源清理方式
由于执行时机不可控且性能低下,JDK9已标记为废弃,推荐使用AutoCloseable接口替代。
十、综合实战:手写一个安全的缓存类
public synchronized CacheEntry getClone(String key) {
CacheEntry entry = store.get(key);
return entry != null ? entry.clone() : null;
}
十一、面试高频考点
| 问题 | 关键要点 |
|---|---|
| hashCode与equals关系 | equals相等则hashCode必等 |
| wait与sleep区别 | wait释放锁,sleep不释放 |
| finalize废弃原因 | 执行时机不可控,性能差 |
通过系统梳理Object类的核心方法,我们不仅掌握了Java对象的基础行为规范,更能深入理解面向对象设计的精髓。这些知识将成为构建健壮Java应用的基石。