谁首先在类加载过程中创建Class <! - ? - >对象?

时间:2015-12-03 16:01:17

标签: java classloader

documentation我找到了:

  

类对象由Java Virtual自动构造   通过调用defineClass方法加载机器作为类   在类加载器中。

我检查了the source code,但未找到要调用的地点defineClass,例如来自loadClass方法。 你能告诉我,根据这个方案,谁和何时拨打defineClass方法:

scheme

图片source

3 个答案:

答案 0 :(得分:10)

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

ClassLoader#defineClass()的调用最终会调用其中一个原生方法defineClass1()defineClass2()。这些方法的C实现可以在src/share/native/java/lang/ClassLoader.c中的OpenJDK中找到。

答案 1 :(得分:5)

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

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

  • findLoadedClass,最后调用Native方法,
  • 致电parent.loadClass
  • findBootstrapClass0原生方法)如果没有parent
  • 最后findClass如果找不到课程。

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

但是,defineClass在哪里被调用?这个抽象类没有地方,但如果你使用GrepCode的参考工具并搜索它的使用位置defineClasssee here results),你会发现很多具体的类最终调用{{1} }。

这不是直截了当的,其中一些类会覆盖definClass,而其他类会调用自己的defineClass,然后调用......等等,但最后它会调用loadClass。< / p>

不要忘记defineClass的{​​{1}}以三种本机方法之一结束,这些方法负责 JVM魔法defineClass,{{1} }和/或ClassLoader

修改

原生函数defineClass0defineClass1调用defineClass2,为1和2函数调用defineClass0

此函数使用Java_java_lang_ClassLoader_defineClass0中定义的ClassLoader.c创建所需的类,并在JVM_DefineClassWithSource中实现。

这最后一个文件定义了jvm.h函数,它最终是创建所需类的函数。最后,此函数调用openjdk\hotspot\src\share\vm\prims\jvm.cpp来分配类。您可以在jvm_define_class_common

中查看最后一个函数的代码

希望它能回答你的问题。

答案 2 :(得分:1)

class NetworkClassLoader extends ClassLoader {
         String host;
         int port;

         public Class findClass(String name) {
             byte[] b = loadClassData(name);
             return defineClass(name, b, 0, b.length);
         }

         private byte[] loadClassData(String name) {
             // load the class data from the connection
              . . .
         }
     }