Java中的getClass()方法是如何实现的?

8

我有这样一段代码:

public class QueueSample {

    public static void main(String[] args) {
        System.out.println(new QueueSample().getClass());
    }

}

它会打印:

class QueueSample

getClass() 方法来自于 Object 类。查看 Object 的源代码,我只能看到如下的方法定义:

public final native Class<?> getClass();

如果这个方法没有在这里实现,那么它是在哪里以及如何被实现的呢?

2
getClass() 是一个本地方法调用。因此,在 JDK 随附的源代码中,您将无法获得该方法的源代码。 - TheLostMind
1
@TheLostMind:那么,本地代码是如何实现它的呢? - batman
@batman 你为什么想知道呢?这是一件非常复杂的事情,完全取决于Java虚拟机的实现方式以及其内部数据结构的功能。它可能因JVM的供应商和版本而异。只要getClass()像规范描述的那样工作,你就不需要知道它是如何实现的。 - Erwin Bolwidt
@batman - 你可以在这里获取源代码:(http://openjdk.java.net/projects/jdk6/)。 - TheLostMind
8
了解事物内部运作的机制,即使只是为了学习而已,也绝不会有任何错。 - Andreas Fester
@Andreas 正如我所说,这需要您了解整个JVM(并且OP需要指定供应商和版本)。如果这是OP的问题,那么它肯定对SO来说“过于宽泛”。 - Erwin Bolwidt
1个回答

7

正如@TheLostMind所提到的,您可以从OpenJDK获取源代码 - 查看较新版本(JDK9),getClass()本地方法的实现方式如下:

链接

JNIEXPORT jclass JNICALL
Java_java_lang_Object_getClass(JNIEnv *env, jobject this)
{
    if (this == NULL) {
        JNU_ThrowNullPointerException(env, NULL);
        return 0;
    } else {
        return (*env)->GetObjectClass(env, this);
    }
}

因此,它基本上是委托给JVM的环境,并使用GetObjectClass()函数返回Class对象。您可以将其用作起点-如果您想深入了解,建议您使用mercurial从http://hg.openjdk.java.net/检查JDK源代码,以便浏览其中。

正如@Holger所提到的,当使用像hotspot这样的JIT编译器时,会有一些性能优化-例如, Hotspot JVM中使用的性能技术说“Object.getClass()是一两个指令。”这意味着上面的代码显示了Object.getClass()的一种可能实现,但是此实现可能会在运行时和/或基于实际的JVM(解释/ JITted,客户端/服务器,Oracle标准/JRockit等)而发生更改。


2
这是可能在解释模式下调用的“普通代码”。很可能热点优化器知道getClass()方法,当它出现在热点中时会将其替换为其他内容,使用调用周围的上下文来预测结果并查看您实际使用结果的方式。请参见https://wikis.oracle.com/display/HotSpotInternals/PerformanceTechniques#PerformanceTechniques-Intrinsics。 - Holger

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