zoukankan      html  css  js  c++  java
  • 两种类别的类加载器(其实是4种)【重点】

    https://www.jianshu.com/p/891c05b0ac05

    CurrentClassLoader是当前方法所属的Class,加载这个Class的ClassLoader,这样有些别扭,其实就是如果A类中有方法调用,在方法调用中用到了B,那么在new的形式下,加载B的ClassLoader一定是加载A的ClassLoader而不是当前线程类加载器new操作时调用当前线程的类加载器,还是调用方的类加载器 文章予以证明)那么在加载B的时候,用来加载B的ClassLoader就是CurrentClassLoader。当然如果通过自定义加载器反射调用就是另外一回事情了
     
        @CallerSensitive
        public static Class<?> forName(String className)
                    throws ClassNotFoundException {
            Class<?> caller = Reflection.getCallerClass();
            return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
        }
    

     

    Class.forName运作时,通过Reflection.getCallerClass(),能够获取是谁调用了Class.forName,这时Reflection.getClassClass() 返回的就是A.class,这样在通过指定ClassLoader来载入B

    通过Reflection.getCallerClass()可以获取到调用Class.forName的类的ClassLoader注意不是forName所在类 Class.class.getClassloader,而是调用链上级

    后者是saturn java 热加载(二)资源文件 spring & logback中第四类,前者是第一类,而Reflection所在类加载器即是第三类,第二类为当前线程类加载器

    如果还是无法理解,就看回想一遍:JDBC注册原理与自定义类加载器解决com.cloudera.hive.jdbc41.HS2Driver的加载【重点】

    归纳一下:

    这个函数代码所在类加载器

    调用这个函数的代码所在类加载器

    当前线程类加载器

      A B.func() 当前线程
    所在类加载器 1 2 3

     class B {  由myClassLoader2加载

      void func(){

        C c = new C();  那么此句究竟用那个类加载器来加载?

        c.func();

    此时C的加载有3种选择

    当前代码所在类加载器myClassLoader2;this.getClass().getClassLoader()

    调用当前代码的代码(**调用B的func函数**)所在的类加载器myClassLoader1;Reflection.getCallerClass().getClassLoader()

    以及当前现场的类加载器myClassLoader3;Thread.currentThread().getContextClassLoader()

      }

    }

    class A {  由myClassLoader1加载

      main() {

        Class cb = myClassLoader2.loadClass("B");

        **调用B的func函数**

      }

    }

    C c = new C();  那么此句究竟用那个类加载器来加载?

    new操作时调用当前线程的类加载器,还是调用方的类加载器

    new操作时调用当前线程的类加载器,还是调用方的类加载器 (二)

    new操作时调用当前线程的类加载器,还是调用方的类加载器 (三)

    三篇文章从实践来解答

    如果一个JNDI的提供方,或者JAXP的提供方,他们的SPI是通过bootstrap加载的,但是他们的实现类必须通过应用ClassLoader甚至是更下层的ClassLoader来加载。那么在其初始化的过程中,需要考虑如果获取到部署了SPI实现的ClassLoader,而给出的方案是使用ContextClassLoader。

    可以看出来CurrentClassLoader对用户来说是自动的,隐式的,而ContextClassLoader需要显示的使用,先进行设置然后再进行使用

  • 相关阅读:
    函数
    循环练习
    循环结构
    分支结构
    C语言关键字
    进制编码
    MAC/Xcode简单操作命令
    Hibernate
    Hibernate
    Hibernate
  • 原文地址:https://www.cnblogs.com/silyvin/p/12166103.html
Copyright © 2011-2022 走看看