JVM 类的加载机制

java引入字节码和JVM机制,提供了强大的跨平台能力。理解Java的类加载机制是深入开发java的必要条件。

今天主要介绍我理解的类加载过程和双亲委派模型。

类加载过程:

类的加载主要分为三个步骤:加载,链接,初始化。

加载过程:将Java字节码数据源读取到JVM中。并映射为jVM可以读懂的结构(类对象)。数据源:jar文件,class文件,网络数据源等,如果输入的不是classFile则抛出异常。

加载是通过加载器去加载:分为bootstrap加载器,扩展,应用加载器,以及用户自己可以定义用户自己的类加载器。(用户可以参与)

Bootstrap ClassLoader    负责加载java基础类,主要是 %JRE_HOME/lib/ 目录下的rt.jar、resources.jar、charsets.jar和class等
Extension ClassLoader     负责加载java扩展类,主要是 %JRE_HOME/lib/ext 目录下的jar和class
App ClassLoader          负责加载当前java应用的classpath中的所有类。

其中Bootstrap ClassLoader是JVM级别的,由C++撰写;Extension ClassLoader、App ClassLoader都是java类,都继承自URLClassLoader超类。
Bootstrap ClassLoader由JVM启动,然后初始化sun.misc.Launcher ,sun.misc.Launcher初始化Extension ClassLoader、App ClassLoader。

自定义的类加载器:

private String path = "D:/user/classpath";
    
    public UserClassLoader(ClassLoader parent, String path) {
        super(parent);
        this.path = path;
    }
    
    @Override
    public Class<?> loadClass(String name) {
        if(name.startsWith("java.")){
            try {
                return super.loadClass(name, false);    
    
            } catch (ClassNotFoundException e) {
                e.printStackTrace();  
            }
        }
        
        byte[] data = loadClassData(name);
        if(data != null)
            return defineClass(name, data, 0, data.length);
        else{
            return null;
        }
    }
    
    /**
     * 根据文件名加载数据
     * @param name
     * @return
     */
    private byte[] loadClassData(String name) {
        FileInputStream is = null;
        ByteArrayOutputStream bos = null;
        try {
            name = name.replace(".", "//");
            File file = new File(path+"/"+name+".class");
            is = new FileInputStream(file);
            bos = new ByteArrayOutputStream();
            int b ;
            while((b = is.read())!=-1) {
                bos.write(b);
            }
            return bos.toByteArray();
        }catch(Exception e){
        }
        finally {
            try {
                is.close();
                bos.close();
            }catch(Exception e) {
                
            }
        }
        return null;
    }
    
    public static void main(String[] args) throws Exception, IllegalAccessException {
        UserClassLoader ul = new UserClassLoader(null,"D:");
        
        Class<?> al = ul.loadClass("com.zxh.java8.test.loader.Animal");
        Method say = al.getMethod("say", null);
        Object alin = al.newInstance();
        say.invoke(alin, null);
    }

 

链接过程:核心步骤,将类定义的信息转化成JVM运行需要的的过程中,可以细分为:

1.验证,包括字节信息是否JVM规范,防止破坏JVM

2.准备,创建类或者接口中的静态变量,并初始化静态变量中的值

3.解析,将常量池中的符号引用替换成直接引用

初始化过程:真正执行初始化的代码逻辑,包括静态字段赋值以及执行静态初始化快的内部逻辑,父类初始化逻辑优先

 

双亲委派:当类加载器试图加载某个类型的时候,除非父类找不到相应类型,否则尽量让这个任务代理给当前加载的父加载器去做。目的避免重复加载java 类型。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值