ClassLoader文档一

一 概述

 ClassLoader本身也是一个对象,这个对象主要是用来加载类(是加载class,不是普通对象)。这个类是一个抽象类,不能实例化对象。只要基于二进制的类名,class loader就会尝试去定位和产生用于组成类定义的数据。一种常用的方

定位:找到已经存在的.class,比如lang包下的文件
产生:JVM动态生成class,比如动态代理

式就是将类名为文件名,然后根据文件系统读取class文件。

二进制类名:
    任何类名必须是符合Java语言规范的二进制类名,该类名作为参数传递给ClassLoader中的方法
    符合Java语言规范的二进制类名
        "java.lang.String" //包含包名的全类名
        "javax.swing.JSpinner$DefaultEditor"//内部类用$表示
        "java.security.KeyStore$Builder$FileBuilder$1"//匿名类用数字表示,1表示第几个内部类
        "java.net.URLClassLoader$3$1"

 每一个类对象都有一个定义这个类对象的ClassLoader,可以通过getClassLoader()获取这个类加载器。

 数组类的类对象不是被ClassLoader产生的,而是JVM运行时自动产生的。数组类的类对象调用getClassLoader()方法返回值与数组中元素的类对象调用getClassLoader()的返回值一样。如果元素类型是原生类型,那么数组类对象调用getClassLoader()的返回值为null。

public class MyTest {
    public static void main(String[] args) {

        int[] ints=new int[2];
        System.out.println(ints.getClass()); //打印class [I  此类并不存在,是JVM动态生成的
       
        MyTest[] myTests=new MyTest[2];
        //每个class对象,都包含了定义此对象的ClassLoader,通过getClassLoader获得
        System.out.println(MyTest.class.getClassLoader());
        System.out.println(myTests.getClass().getClassLoader());
         控制台输出:
         sun.misc.Launcher$AppClassLoader@18b4aac2
         sun.misc.Launcher$AppClassLoader@18b4aac2
         可知:数组类的类对象调用getClassLoader()方法返回值与数组中元素的类对象调用getClassLoader()的返回值一样。
        
        
        System.out.println(ints.getClass().getClassLoader());
         控制台输出:
         null
         可知:如果元素类型是原生类型,那么数组类对象调用getClassLoader()的返回值为null。
        
    }
}

 程序实现ClassLoader类的目的是扩展JVM动态加载类的方式,比如从网络环境加载类等。

 ClassLoader使用双亲委托模型去搜索class和资源,每一个ClassLoader都有一个与之相关联的父ClassLoader。当需要搜索class和资源时,在本ClassLoader查找class和资源之前会委托给父ClassLoader去查找class和资源。虚拟机的根ClassLoader是bootstrap class loader,bootstrap class loader没有父加载器,它本身是其他的父加载器。

 支持并发加载的加载器被称为parallel capable加载器,parallel capable加载器需要在类初始化是调用ClassLoader.registerAsParallelCapable方法。默认系统的类加载器已经注册了,但是子类仍需注册。

 如果不是严格的双亲委托模型,类加载器则需要parallel capable,否则类的加载可能导致死锁,因为所需要保持在整个加载过程。

 一般来说,类的来源是文件系统,但是也可能来自于网络或者动态生成。ClassLoader的defineClass方法,将参数中的数组转为class对象。

 被类加载器创建的对象的方法和构造方法中可能会引用其他的class,JVM调用loadClass方法去定义被引用的类。

二 构造方法

//类加载是基于双亲委托的,因此需要设置父加载器是谁
//该构造方法就是 使用参数的parent去构建一个新的loader
protected ClassLoader(ClassLoader parent)

//使用系统类加载器作为父加载器去构建一个新的loader
protected ClassLoader() {
        this(checkCreateClassLoader(), getSystemClassLoader());
    }

你可能感兴趣的:(ClassLoader文档一)