------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
Java虚拟机中可以安装多个类加载器,系统默认安装三个主要类加载器,每个类负责加载特定位置的类:BootStrap;ExtClassLoader;AppClassLoader
类加载器也是Java类,是java类的类加载器本身也要被类加载器加载,显然必须要有一个类加载器不是java类,这正是第一个类加载器BootStrap。
Java虚拟机中的所有类装载器采用具有父子关系的树形结构进行组织,在实例化每个类装载器对象时,需要为其指定一个父级类装载器对象或者默认采用系统类装载器为其父级类加载。
类加载器的委托机制
当Java虚拟机要加载一个类时,首先当前线程的类加载器去加载线程中的第一个类。
如果类C中引用了类D,Java虚拟机将使用加载类C的类装载器来加载类D。还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。每个类加载器加载类时,又先委托给它的上级类加载器。当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛ClassNotFoundException,不是再去找发起者类加载器的子类,因为没有getChild方法,即使有,父类有多个子孙类,父类也无法知道应该找那个类。
类加载器的特点
1、运行一个程序时,总是由AppClassLoader开始加载指定的类。
2、在加载类时,每个类加载器会将加载任务上交给它的父类,如果它的父类找不到,再由自己去加载。
3、Bootstrap Loader是最顶级的类加载器了,它的父类加载器为null.
类加载过程简单解释
当在命令行下执行:
java HelloWorld命令的时候,JVM会将HelloWorld.class加载到内存中,并形成一个Class的对象HelloWorld.class。
它的过程就是类加载过程:
1、寻找jre目录,寻找jvm.dll,初始化JVM;
2、产生一个BootstrapLoader;
3、BootstrapLoader自动加载Extended Loader(标准扩展类加载器),并将它的父类加载器设为Bootstrap Loader。
4、BootstrapLoader自动加载AppClass Loader,并将它的父类加载器设为ExtendedLoader。
5、最后由AppClassLoader加载HelloWorld类。
以上就是类加载的最一般的过程。
类加载有三种方式:
1、命令行启动应用时候由Java虚拟机初始化加载
2、通过Class.forName()方法动态地加载
3、通过ClassLoader.loadClass()方法动态地加载
代码体现:
public class HelloWorld {
public static void main(String[] args) throws ClassNotFoundException {
//获取HelloWorld的类加载器
ClassLoader loader = HelloWorld.class.getClassLoader();
System.out.println(loader);
//使用ClassLoader.loadClass()加载类,不会执行初始化块
loader.loadClass("Test2");
//使用Class.forName()加载类,默认会执行初始化块
// Class.forName("Test2");
//使用Class.forName()加载类,并指定类加载器,初始化时不执行静态代码块
// Class.forName("Test2",false, loader);
}
}
public class Test2 {
static {
System.out.println("静态初始化块执行了!");
}
}