当前位置:   article > 正文

【JVM学习笔记】---类加载器Classloader源码分析_jvm类加载器源码

jvm类加载器源码
  1. 类加载器是负责加载类的对象。 ClassLoader是一个抽象类。 给定一个类的***binary name *** ,类加载器应该尝试***定位或生成***构成类的定义的数据。 典型的策略是将名称转换为文件名,然后从文件系统中读取该名称的“类文件”。
    PS:
    (1)什么是Binary names?
    任何类名以字符串参数的形式提供给ClassLoader的方法,其中字符串参数必须是The Java™ Language Specification的如上定义的二进制名称,有效的类名的示例包括:
    “java.lang.String”
    “javax.swing.JSpinner D e f a u l t E d i t o r " " j a v a . s e c u r i t y . K e y S t o r e DefaultEditor" "java.security.KeyStore DefaultEditor""java.security.KeyStoreBuilder$FileBuilder$1”(1代表FileBuilder的第一个匿名内部类)
    “java.net.URLClassLoader$3$1”
    (2)定位与生成的含义:
    定位:数据已经真真切切存在于某个地方,进而找到该地方,例如我们自己所编写的类,或者使用JDK源码包里的类,如Java.lang.string。
    生成:运行期动态生成的一些类,运行期之前不存在,如动态代理。

    2. 每个Class对象包含一个获得加载该类的加载器所对应的方法:public ClassLoader getClassLoader​()
    3. 数组类所对应Class对象不是由类加载器创建的,而是根据Java运行时的要求自动创建。除此之外,其他类的Class对象一定是由类加载器创建的。 Class.getClassLoader()返回的数组类的类加载器与其元素类型的类加载器相同; 如果元素类型是原始类型,则数组类没有类加载器。
    代码:public class MyTest15{
    public static void main(String[] args){
    String[] strings=new String[2];
    System.out.println(strings.getClass());
    System.out.println(strings.getClass().getClassLoader());//输出为null,因为String类型是由根加载器加载的。
    MyTest15[] mytest15=new MyTest15[2];
    System.out.println(mytest15.getClass().getClassLoader()); //输出应用类加载器
    int[] arr=new int[2];
    System.out.println(arr.getClass().getClassLoader()); //输出null,此null非彼null
    }
    }

    4.创建的目的是为了扩展Java虚拟机动态加载类的方式(JVM默认的动态加载类的方式是双亲委托机制)。
    5. 安全管理员通常可以使用类加载器来指示安全域。
    6. Java虚拟机以平台相关的方式从本地文件系统加载类。 然而,一些类可能不是源于文件; 它们可以来自诸如网络的其他来源,或者它们可以由应用构建。 方法defineClass将字节数组转换为类别Class的实例。 这个新定义的类的实例可以使用Class.newInstance创建。
    7. 类加载器创建的对象的方法和构造函数可以引用其他类。 要确定所引用的类,Java虚拟机调用最初创建该类的类加载器的loadClass方法。

例如,应用程序可以创建一个网络类加载器来从服务器下载类文件。 示例代码可能如下所示:
ClassLoader loader = new NetworkClassLoader(host, port);
Object main = loader.loadClass(“Main”, true).newInstance();
. . .

  1. 网络类加载器子类必须定义方法findClass和loadClassData以从网络加载类。 一旦下载构成类的字节,它应该使用方法defineClass创建一个类实例。
    示例实现是:
    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
           . . .
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    }

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号