在学习类加载机制之前,我们先了解一下类加载器,因为类加载器是类加载机制的前提。类加载器的主要任务就是:根据一个类的全限定名,将该类的字节码文件加载进JVM中,然后转换为一个对应类的Java.lang.Class对象实例。程序员也可以自定义类加载器,一般的将派生于抽象类ClassLoader的类加载器都划分为自定义类加载器。
在程序中我们最常见的类加载器只有三个:
- Bootstrap ClassLoader; (启动类加载器)
- ExtClassLoader;
- AppClassLoader;(加载classpath路径下的所有类,即自己编写的类)
1.Bootstrap ClassLoader:
Bootstrap ClassLoader:由C++语言编写,嵌套在JVM内部。
2.ExtClassLoader,AppClassLoader:
ExtClassLoader,APPClassLoader派生于ClassLoader,用Java语言编写。
public class Test1 { public static void main(String[] args) { /* * 获得class对象的三种方式: * 1.类名.class; * 2.对象.getClass(); * 3.Class.forName("类的全限定名"); * */ //Bootstrap ClassLoader加载的是: JAVA_HOME/lib目录下的 ClassLoader loader = System.class.getClassLoader(); System.out.println((loader==null)?null:loader.getClass().getName()); //ExtClassLoader加载的是:JAVA_HOME/lib/ext目录下的 System.out.println(CollationData_ar.class.getClassLoader().getClass().getName()); //AppClassLoader加载的是:classPath: System.out.println(Test1.class.getClassLoader().getClass().getName()); } } //打印结果如下: null //由于BootstrapClassLoader是由C++编写 并嵌在JVM的内部 sun.misc.Launcher$ExtClassLoader sun.misc.Launcher$AppClassLoader
抽象类ClassLoader:
当用户想自定义类加载器时,只需继承ClassLoader抽象类,并重写findClass()方法,使用时在程序中调用loadClass()方法即可实现类的加载操作。
ClassLoader类中常用的方法:
- getParent(); //返回该类加载器的超类加载器
- loadClass(String name); //加载名称为name,返回 java.lang.Class类的实例
- findClass(String name); //查找名称为name,返回java.lang.Class类的实例
- findLoadedClass(String name); //查找名称为name已经被加载过的类,返回结果为:java.lang.Class类的实例
- defineClass(String name,byte[] b,int off,int len); //将字节数组中的内容转化成一个类,返回 java,lang.Class类的实例
- resolveClass(Class<?> c); //连接指定的一个Java类
注意:基于双亲委派模型,除了启动类加载器(BootstrapClassLoader),每个类加载器都有一个超类加载器。例如:AppClassLoader的超类加载器就是ExtClassLoader,ExtClassLoader的超类加载器就是BootstrapClassLoader。此外 自定义的类加载器的超类加载器是AppClassLoader。
public class Test2 { public static void main(String[] args) { //获得Test2的类加载器 ClassLoader classLoader = Test2.class.getClassLoader(); System.out.println("当前类加载器:"+classLoader.getClass().getName()); //获得该类加载器的超类加载器 ClassLoader parent = classLoader.getParent(); System.out.println("超类加载器:"+parent.getClass().getName()); } } //打印结果如下: 当前类加载器:sun.misc.Launcher$AppClassLoader 超类加载器:sun.misc.Launcher$ExtClassLoader