谁首先在类装入过程中创建类<>对象?编辑

2022-09-03 02:06:14

在我发现的文档中

类对象由 Java 虚拟机在装入类时自动构造,并通过调用类装入器中的 defineClass 方法自动构造。

我检查了源代码,但没有找到要调用的地方,例如从loadClass方法。你能告诉我,请,根据这个方案,谁和什么时候调用方法:defineClassdefineClass

scheme

图片来源


答案 1

在调用 期间调用该方法。但是,这不是直接在类中完成的,而是在其子类之一中完成的,例如在 .defineClass()ClassLoader#loadClass()java.lang.ClassLoaderURLClassLoader#findClass()

对其中一个本机方法 defineClass1() 或 defineClass2() 的调用结束。这些方法的C实现可以在OpenJDK的src/share/native/java/lang/ClassLoader.c中找到。ClassLoader#defineClass()


答案 2

java.lang.ClassLoader真是大类。使用你的 GrepCode 链接(适用于 java 6-b14 版本),你可以在第 267 行找到公共方法。loadClass

此方法在第 308 行调用受保护的方法,此方法尝试使用以下命令加载预先加载的类:loadClass

  • findLoadedClass它最终调用本机方法,
  • parent.loadClass
  • findBootstrapClass0 (也是一个本机方法)如果没有 ,parent
  • 最后,如果未找到类。findClass

这很重要,因为尝试重用已经加载的 clases,请记住。ClassLoader

但是,在哪里调用?这个抽象类中没有位置,但是如果您使用GrepCode中的引用工具并搜索使用它的位置(请参阅此处的结果),您会发现许多最终调用的具体类。defineClassdefineClassdefinClass

这并不简单,其中一些类,覆盖而另一些类调用它自己的,然后调用...等等,但最后它调用.defineClassloadClassdefineClass

不要忘记负责 JVM 魔术的三种本机方法之一的结束:、 和/或defineClassClassLoaderdefineClass0defineClass1defineClass2

编辑

本机函数调用来自 1 和 2 个函数,并且对于 1 和 2 个函数也是如此。defineClass0Java_java_lang_ClassLoader_defineClass0ClassLoader.c

此函数使用 中定义并在 中创建所需的类。JVM_DefineClassWithSourcejvm.hopenjdk\hotspot\src\share\vm\prims\jvm.cpp

最后一个文件定义了函数,该函数最终是创建所需类的函数。最后,此函数调用以分配类。您可以在jvm_define_class_commonJNIHandles::make_localopenjdk\hotspot\src\share\vm\runtime\jniHandles.cpp

希望它能回答你的问题。


推荐