ClassLoader类加载器

类加载器:
运行java程序时,首先运行JVM,再将java class加载到JVM中运行,负责加载java class的这部分就叫ClassLoader(把二进制文件识别、读取到内存中的功能模块)

JDK内置的三大类加载器:

  • BootStrap:启动类加载器(加载object,String等基础类)
    负责将存放于java_HOME\lib目录下的能被jvm识别的所有类库(例如rt.jar等java基础类库)加载到jvm中。使用C++语言实现,是jvm自身的一部分,独立于jvm外部,并且无法被jvm程序直接引用。
  • ExtClassLoader:扩展类加载器
    负责将存放于java_HOME\lib\ext(xml文件解析类、界面框架类)目录下的所有能被jvm识别的类库加载到jvm中。使用java语言实现,可以被java程序直接引用
  • AppClassLoader:应用程序类加载器(加载用户classpath指定的类库)
    使用java程序实现,如果用户没有自定义类加载器,则AppClassLoader就是程序中默认的类加载器。
class Loader{}
public class ClassLoaderDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        Class cls = Class.forName("com.gitwh.Loader");
        System.out.println(cls.getClassLoader());
        System.out.println(cls.getClassLoader().getParent());
        System.out.println(cls.getClassLoader().getParent().getParent());
    }
}

在这里插入图片描述
可以看到不能获得BootStrap,为null
双亲委派模型:四种类加载器的层次关系称为双亲委派模型
工作流程:如果一个类加载器收到加载请求,首先自己不会去尝试加载此类,而是将类加载请求委托给父加载器完成,每一层类加载器都是如此。只有当父加载器无法加载此类时,子加载器才会尝试自己去加载。
存在意义:双亲委派模型对于保证java程序的稳定运行十分重要,保证类加载的安全性
作用:如果用户定义了与基础类库同名的类这时双亲委派模型就起作用了
以Object为例:自身定义的与基础类库同名的类会先交给顶层的BootStrap类加载器,但此时Object已经在这一层被加载了,不会扔回底端加载器AppCalssLoader,所以这个类不会被加载。这时就防止了用户定义的同名类(类全称)将原本存在的类冲击掉。
比较两个类相等的条件:这两个类是由同一个加载器加载的,否则即使两个类来自同一个Class文件,被同一个jvm加载,只要类加载器不同,就不相等(因为本质是class对象不相等)。
自定义类加载器
自定义类加载器的两个重要步骤:

  • 自定义类继承ClassLoader类
  • 在自定义类中覆写findClass()方法

findClass方法的作用就是根据类名加载.Class字节码,

public Class<?> findClass(String className) throws ClassNotFoundException {
        byte[] data = null;
        try {
            data = this.loadClassData();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //将字节码转换为Class,返回Class对象
        return super.defineClass(data,0,data.length);
    }

defineClass()方法:将输入的byte数组装换为一个Class对象

protected final Class<?> defineClass(byte[] b, int off, int len)
        throws ClassFormatError
    {
        return defineClass(null, b, off, len, null);
    }

loadClassData()方法:获得.class字节码数组

public byte[] loadClassData() throws Exception{
        InputStream in = new FileInputStream(
                "C:\\Users\\xptyxx20170501A\\Desktop\\Test.class");
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] data = new byte[20];
        int temp = 0;
        while ((temp = in.read(data))!=-1){
            bos.write(data,0,temp);
        }
        byte[] result = bos.toByteArray();
        in.close();
        bos.close();
        return result;
    }

        MyClassLoader myClassLoader = new MyClassLoader();
        Class<?> cls = myClassLoader.findClass("com.gitwh.Test");
        System.out.println(cls.getClassLoader());
        System.out.println(cls.getClassLoader().getParent());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值