关于jvm运行机制--类加载器(二)

本文深入探讨JVM为何采用双亲委派机制加载类,分析其对Java核心类库安全性的保障,防止类冲突与自定义类取代核心类的问题。同时,介绍了三种类加载器之间的关系及其实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上篇文章介绍到类加载器的双亲委派机制,但是jvm的类加载器为什么要采取这种的实现方式呢?
1.可以确保java核心类库的安全放着了jar包的冲突,例如所有的Java的应用可能都会使用java.lang.Object这个类,这个类是由启动类加载器加载的,如果他的子类加载器也加载了同样的类或者版本不一样的类可能就会产生冲突。
2.确保了Java的核心类不会被自定义的类所取代,假如自定了和核心类同名的类,可以保证这两个的隔离,从而不会被取代。
3.不同的类加载器可以为相同的类创建不同的命名空间从而是相同名字的两个类可以共存在jvm中。
接下来介绍一下三种类加载器的关系以及对其源码进行分析:
首先看下加载器的上层结构:
在这里插入图片描述
ExtClassLoader和AppClassLoader都继承自自URLClasssLoader,BootClassloader是用C++语言实现的(此处暂时不做分析),URLClassLoader:继承自SecureClassLoader,支持从jar文件和文件夹中获取class,继承于classload,加载时首先去classload里判断是否由bootstrap classload加载过,1.7 新增实现closeable接口,实现在try 中自动释放资源,但捕捉不了.close()异常
关于系统类加载器和扩展类加载器的实现都在sun.misc.Launcher这个类中,两个类都是Launcher的子类具体实现代码如下(方法实现已经省略):

static class AppClassLoader extends URLClassLoader {
    public static ClassLoader getAppClassLoader(final ClassLoader var0) throws IOException {
      
    }

    AppClassLoader(URL[] var1, ClassLoader var2) {
        super(var1, var2, Launcher.factory);
    }

    public Class loadClass(String var1, boolean var2) throws ClassNotFoundException {
       
    }

    protected PermissionCollection getPermissions(CodeSource var1) {
      
    }

    private void appendToClassPathForInstrumentation(String var1) {
     
    }

    private static AccessControlContext getContext(File[] var0) throws MalformedURLException {
    
    }

    static {
        ClassLoader.registerAsParallelCapable();
    }
}

下面是扩展类加载器的实现:

static class ExtClassLoader extends URLClassLoader {
    public static Launcher.ExtClassLoader getExtClassLoader() throws IOException {
       
    }

    void addExtURL(URL var1) {
   
    }

    public ExtClassLoader(File[] var1) throws IOException {
   
    }

    private static File[] getExtDirs() {
  
    }

    private static URL[] getExtURLs(File[] var0) throws IOException {
     
    
    }

    public String findLibrary(String var1) {
     
            
    }

    private static AccessControlContext getContext(File[] var0) throws IOException {
      
    }
}

只有AppClassLoader重写了父类的loadClass方法,扩展类加载器是继承了父类的loadClass方法,在这个方法中都会实现双亲委派的逻辑:

	if (parent != null) {
                    c = parent.loadClass(name, false);
                } else {
                    c = findBootstrapClassOrNull(name);
                }

同时在loadClass方法中会调用findLoadClass方法去判断是否该类被加载过,如果被加载过便不再被加载。
如果是自定义的类加载器我们去继承ClassLoader或者URLClassLoader都可以,然后重写其中的方法,在自定义类加载器后会默认加载父类加载器的无参构造方法,在其中会将AppClassLoader设置为自定义加载器的父类加载器,如果想自定义类的父类加载器需要显示指定构造方法:

protected ClassLoader(ClassLoader parent) {
    this(checkCreateClassLoader(), parent);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值