Object类中可被反射调用的public native方法(如hashCode、equals、wait等)需满足public且非final,getClass()因final不可反射调用;真正底层JVM native实现(如FastHashCode)不暴露于Java方法表,反射无法访问,应使用System.identityHashCode获取原始哈希码。

Object 类本身没有“底层原生方法”供反射直接调用——它的 getClass()、hashCode()、equals()、toString() 等都是 Java 层的普通方法(部分由 JVM 内置优化,但不暴露为 JNI 可反射调用的 native 方法)。Java 反射机制无法动态调用 JVM 内部的 native 实现(如 Object.hashCode() 底层可能映射到 C++ 的 objectHash()),因为这些 native 方法未通过 public native 声明暴露在 Java 接口层面,也不在 Method 可获取的列表中。
Object 类中真正可被反射调用的方法只有 public 非 final 的实例方法
虽然 Object 类定义了多个方法,但反射能访问的仅限于:
-
getClass():public final,不能通过反射调用(final 方法可获取但 setAccessible(true) 无效) -
hashCode()、equals(Object)、toString()、clone()、notify()、notifyAll()、wait()及重载:public,非 final(clone()和wait()等是 native,但声明为 public native,因此可通过反射调用) -
finalize():protected,需 setAccessible(true) 才能访问(且已被标记为 deprecated)
如何用反射调用 Object 的 public native 方法(如 hashCode)
以 hashCode() 为例,它虽是 native,但签名明确、public、非 final,反射可正常 invoke:
Object obj = new Object();
try {
Method method = Object.class.getDeclaredMethod("hashCode");
method.setAccessible(true); // 实际上不需要(已是 public),但习惯性写上
int result = (int) method.invoke(obj);
System.out.println(result); // 输出与 obj.hashCode() 一致
} catch (Exception e) {
e.printStackTrace();
}
注意:getClass() 是 final 方法,反射调用会抛出 IllegalAccessException;notify()、wait() 等需在同步上下文中调用,否则抛出 IllegalMonitorStateException。
立即学习“Java免费学习笔记(深入)”;
为什么不能调用 JVM 底层真正的 native 实现?
JVM 对 Object 方法做了深度内联和优化(例如 System.identityHashCode() 绕过对象重写的 hashCode()),但这些实现不通过 Java 方法表暴露。反射只能操作 java.lang.Class 描述的 Java 层方法,而:
- JNI 函数(如
JVM_IHashCode)不对应任何 Java 方法签名 - HotSpot 中
ObjectSynchronizer::FastHashCode等 C++ 函数不对外可见 - 即使使用 Unsafe 或 JNR 等底层工具,也属于 JVM 实现细节,不可移植、不安全、不推荐
替代方案:需要底层标识时用 System.identityHashCode
若目标是绕过重写的 hashCode() 获取对象原始哈希码,应直接使用:
int identityHash = System.identityHashCode(obj); // 安全、标准、高效
该方法内部调用 JVM 原生逻辑,但封装良好,无需反射,也不依赖具体实现。
不复杂但容易忽略:反射不是万能钥匙,JVM 的关键基础设施(如对象头操作、内存布局、锁机制)不会开放为可反射调用的 Java 方法。合理使用标准 API 比强行反射更可靠。


















