类加载机制解析

一、类加载过程
请添加图片描述
将多个java文件编译打包成可运行jar包,通过java命令运行某个主类的main函数启动程序,此时类加载器会首先把该主类加载到jvm(已经使用到),jar包中其他类,在使用到时才开始执行加载流程
加载流程
1)加载:通过io流读入字节码文件,使用到类时才会进行加载,比如main函数,new对象等
2)验证:校验字节码文件的正确性
3)准备:将静态变量分配内存,并赋默认值(如int a = 0)
4)解析:将符号引用替换成直接引用,比如将静态变量(main方法)替换成所存内存的指针或句柄,这个过程叫静态链接,在类加载时完成。另外一种为动态链接,在程序运行期间完成该过程
5)初始化:将静态变量初始化为指定的值(如int a = 6),执行静态代码块

二、类加载器与双亲委派机制
类的加载流程由类加载器完成,类加载器分为以下几种:
1)引导类加载器(bootstrap class loader),加载java 核心jar包,jre/lib/.jar等
2)扩展类加载器(ExtClassLoader),加载jre/ext/
.jar
3)系统类加载器,也就是应用程序类加载器(AppClassLoader),加载ClassPath下的类包,也就是应用程序自己写的类
4)自定义加载器:加载自定义路径下的类包

类加载器示例

    public static void main(String[] args) throws ClassNotFoundException {
        System.out.println(String.class.getClassLoader());
        System.out.println(com.sun.crypto.provider.DESKeyFactory.class.getClassLoader().getClass().getName());
        System.out.println(TestJDKClassLoad.class.getClassLoader().getClass().getName());
        System.out.println(ClassLoader.getSystemClassLoader().getClass().getName());
    }

输出:
null
sun.misc.Launcher E x t C l a s s L o a d e r s u n . m i s c . L a u n c h e r ExtClassLoader sun.misc.Launcher ExtClassLoadersun.misc.LauncherAppClassLoader
sun.misc.Launcher$AppClassLoader

自定义加载器实现:
继承ClassLoader类即可,主要有2个核心方法
1)loadClass(String,Boolean),实现了双亲委派机制
2)findClass(String name),默认是抛出异常,自定义的话重写该方法即可

private byte[] loadByte(String name) throws IOException {
   name = name.replaceAll("\\.","/");
   FileInputStream fileInputStream = new FileInputStream(classPath+"/"+name+".class");
   final int len = fileInputStream.available();
   byte [] data = new byte[len];
   fileInputStream.read(data);
   fileInputStream.close();
   return data;
}

@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
   try {
       // 读取硬盘上的字节码文件
       final byte[] data = loadByte(name);
       // 根据字节码文件创建class对象
       return defineClass(name,data,0,data.length);
   } catch (IOException e) {
       e.printStackTrace();
       throw new ClassNotFoundException();
   }
}

双亲委派机制
大致流程:
1)判断指定的类是否已经加载过,如果已经加载 则直接返回
2)如果该类没有加载过,则判断有没有父加载器,有的话则使用父加载器进行加载,或者调用bootstrap加载器进行加载
3)当父加载器或者bootstrap加载器都找不到该类,则调用当前类的加载器findClass完成加载

双亲委派机制好处

  • 安全,始终由父加载器优先加载,保证核心类库不被篡改,且不能以java开头命名类包
  • 唯一性,保证jvm中只存在一个相同类
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值