为什么hashCode()和getClass()是本地方法?

41

我查看了Object类的源代码,发现getClass()方法的声明是:

public final native Class<?> getClass();

hashCode() 的声明是:

public native int hashCode();

这个类中的这两个方法为什么是native方法,我该如何获取这些方法的源代码?


15
非重复问题 - 问题提问者知道“native”的意思,但想知道为什么这两种方法具体是“native”。 - Alnitak
5
hashCode()方法是本地方法,因为数据存储的方式可能因操作系统的不同而有所区别。我不确定为什么getClass()方法也是本地方法;可能是由于多态性实现的差异导致的。 - FThompson
1
@Vulcan getClass() 是 final 的,所以你无法覆盖它并破坏类型系统。 - user207421
@EJP,我知道为什么它是final,但不知道为什么它是native。正如我在上一条评论中所说的,我唯一的猜测可能是由于多态性的不同实现。 - FThompson
1
好的,hashCode 可以使用 System.identityHashCode 实现。 - zch
3个回答

51

你可以在这里找到本地方法的完整源代码here

希望这对你有用。

这些是本地方法,因为它们需要与机器交互。在这里,使用C语言编写了机器相关的代码,这些代码不包含在源包或位于Java Runtime Environment(JRE)的lib位置的rt.jar中。

本地方法之所以存在可能是因为性能原因。由于使用C级别的编程,因此性能可能得到改善,因此他们可能已经使用C语言编写了本地代码。

这些方法是本地方法,因为它们涉及本地数据。 hashCode方法返回一个依赖于指向堆上对象的内部表示的指针的整数值。 getClass方法必须访问表示编译程序类层次结构的内部vtblvirtual function table)。在核心Java中,这两个都是不可能的。


1
hashCode 方法返回一个整数值,该值取决于指向堆上对象的指针的内部表示。从查看源代码(http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/tip/src/share/vm/runtime/synchronizer.cpp#l555)来看,似乎并非如此。 - Matthias Braun

40

可以在这里找到Object类的源代码。

该源代码包含了getClass()方法的实现(请查看第58行)。hashCode被定义为函数指针JVM_IHashCode(请查看第43行)。

JVM_IHashCode在jvm.cpp中定义。请查看从第504行开始的代码。这又调用了在synchronizer.cpp中定义的ObjectSynchronizer::FastHashCode。请查看第576行处的FastHashCode和第530行处的get_next_hash的实现。

可能,这些方法是为了性能和实现上的实际问题而使用本地方法实现的。

例如,根据javadoc,hashCode通常通过“将对象的内部地址转换为整数”来实现。这个内部地址在java sdk中不可用,必须实现为本地方法。

请阅读是否可以找到Java本地方法的源代码?。还请阅读这篇博客文章Object.hashCode实现,它提供了更多细节。但是它错误地断言hashCode不是从对象的标识生成的。

希望有所帮助。


那么我们如何说JVM是平台无关的? - Bhavik Ambani
这会如何破坏平台独立性?对于任何对象,hashCode 不需要在不同平台上相同。事实上,在同一平台上,它甚至在不同的运行中也可能不同。尝试使用以下代码进行测试:public class TestHashCode { public static void main(String[] args) { Object o = new Object(); System.out.println(o.hashCode()); } } - krishnakumarp
3
这是术语方面的细微区别,但 JVM 并非跨平台,而是平台相关的部分,它在特定平台上执行平台无关的Java字节码。 - hyde
@hyde,这就是我所说的,参考我的答案。 - Bhavik Ambani

2

这些方法的信息可以在头文件(对于类)或其他地方(对于hashCode)中找到。这不是你能在Java中实现的东西。这些方法的源代码在JVM的源代码中。例如,你可以下载OpenJDK的源代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接