一、什么是类加载器
类加载器是一个用来加载类文件的类,Java源代码通过javac编译器编译成类文件,然后JVM来执行类文件中的字节码来执行程序。需要注意的是,只有被同一个类加载器加载的类才可能会相等。相同字节码被不同的类加载器加载的类不相等。
二、类加载器分类
1.启动类加载器
由C++实现,是虚拟机的一部分,用于加载javahome下的lib目录下的类;
2.扩展类加载器
加载javahome下/lib/ext目录中的类;
3.应用程序类加载器
加载用户类路径上的所指定的类库,也就是我们所用的类加载器;
三、自定义加载器
在jvm中,除了以上三种类加载器外,我们还可以自定义加载器,自定义加载器的方法有三步
1.定义一个类继承classloader
2.重写loadClass方法
3.实例化class对象
我们看下面的例子:
package com.example.demo; import java.io.InputStream; public class Test1 extends ClassLoader{ @Override public Class<?> loadClass(String name) throws ClassNotFoundException { //name的值为com.example.demo.Test1,他是类的绝对路径 //截取name后 fileName的值为Test1.class //加上.class表示这是个class文件 String fileName=name.substring(name.lastIndexOf(".")+1)+".class"; //加载这个class文件 InputStream input=getClass().getResourceAsStream(fileName); //判断input是否为空 //为空就证明当前文件夹下没有这个文件 //如果为空就让父类加载器去加载它 if (input==null) { return super.loadClass(name); } //如果不为空,就用当前的类加载器进行加载 try { //简单的IO流操作,用创建一个byte数组,然后将输入流输入数组 byte [] buff=new byte[input.available()]; input.read(buff); //方便测试,我们加上一行代码 System.out.println("自定义类加载器启动"); //当读取后,我们需要实例化class对象 //在这里我们使用java为我们提供的defineClass方法实例化对象 //defineClass的参数意思:要加载类的绝对路径,读取的数组,从第几位开始读,读到第几位结束 return defineClass(name, buff, 0, buff.length); } catch (Exception e) { throw new ClassNotFoundException(); } } }