Java Se:自定义ClassLoader

 

  
 JVM是怎么理解java.lang包中的接近的?JVM又是怎知道我们运用被的类的?我们的采取中有目共睹是来某个类,
但是JVM却弃来ClassNotFoundException,这是干什么?XxxImpl类已经实现了接口Xxx,但是也抛出XxxImpl
does not extend from Xxx,这是为何?使用类型转换时,可能会见弃来
aa.bb.cc.XXX can not cast to
aa.bb.cc,这又是怎?等等诸多像样诡异情景,其实还是为ClassLoader。

     
 了解反射的人且清楚各个一个类都出一个Class对象同之对应,那么这个Class对象又是呀来之也罢?

 

若果如了解Class的基本知识,可以参见:

http://blog.csdn.net/irelandken/article/details/7048817

http://tyrion.iteye.com/blog/1958814

http://www.blogjava.net/lihuaxajh/articles/94371.html

http://www.javaworld.com/article/2077332/core-java/get-a-load-of-that-name.html

http://www.javaworld.com/article/2075796/java-platform/java-101--class-and-object-initialization.html

 

我对ClassLoader的理解

脚是自我看了这些博客、文章后,并从定义了一个ClassLoader进行测试后的晓:

 

1)ClassLoader加载一个近似时,不见面加载类中持有的好像,而是在运转时根据要以的近乎动态加载的,即按照需要加载。

2)ClassLoader加载一个好像时,也会见加载其父类(包括接口)

3)当前类A在运行时,类中设利用的其余的接近(B,C,D类等),默认是由于时类A的加载器来加载的。

4)类型强制转换时,先判断是无是跟一个近似加载器,如果不是,就非能够开展转换。一个对象A但于由BootstrapCLassLoader加载的类(A的父类或者接口)转换时,好像不以这过程。

5)Thread#contextClassLoader可以用来在切换类加载器。

6)默认情况下,线程的上下文加载器采用的及父线程的上下文加载器是同一个。

7)Class.forName(“xxx”)、Xxx.class
的加载器,使用的都是眼下相近的接近加载器。

 

脚是由定义类加载器

代码清单:

 图片 1

下面就是对这些类似做一个简单易行的征:

StringUtil.java

 图片 2

StringUtil中只是发生三三两两只道,用于判断字符串空值。写这个看似实在是从来不必要,但是在测试着呢可见见成效的。

DebugUtil.java

 图片 3

 只是为从有有些消息。

Person.java

 图片 4

及时是一个超人的Java Bean,没有什么而说的。

ClassLoaderTestRunner.java

 图片 5

旋即是业务类。从代码上看吗是坏简短的,只是加载了Person类,创建一个Person对象,输出一些音。

是类
既可行使系统默认的好像加载器加载测试(main方法),也可以动用于定义之近乎加载器来测试。

 

自定义ClassLoader

时常用之加载机制起半点种植:委托加载机制、子类优先加载

1)委托加载机制loadClass()的流程:

(1) 判断是否曾经加载是仿佛

(2) 如果无加载,当前类似加载器的父加载器加载,即实行loadClass()方法。

(3) 如果手上相近加载器的有父加载器都没加载到即叫眼前加载器调用
findClass()加载。

 

2)子类优先加载器的流水线:

(1) 判断是否曾经加载是类似

(2) 当前类加载器直接加载类

(3) 加载不至才挪父类加载流程。

 

JDK中默认的加载方式是1),也尽管是托加载机制。

 

自定义类加载器,一般会更写loadClass、findClass。

 图片 6

delegate字段是用于指定是否采取默认的信托加载机制。

 图片 7

当时是从定义之加载类的道。流程是:

    1)判断该加载器是否都加载了这近乎,为了避免重新的加载。

    2)如果delegate=true,委托加载,就利用默认的加载方式。

    3)如果delegate=false,
排除给保障的切近,然后使下的自定义的findClass来加以载类。上述过程要出现了生,仍然会利用默认的加载方法。

 

 图片 8

findClass是因类名加载并定义一个Class对象。这个点子勾勒的充分粗劣,只是为测试ClassLoader。

 

 

紧接下去便足以利用ClassLoaderTest.java来测试了:

 图片 9

有关这测试的简便说明:

1)这个测试中的有关类,如String, UrlClassLoader, ClassLoader,Object,
Thread,Runnable,Exception等还是由默认的体系加载器(SystemClassLoader)或者其父类(ExtClassLoader、BootstrapClassLoader)来加载的。当前这个运行时,这个仿佛(ClassLoaderTest)的加载器是SystemClassLoader。

2)加载ClassLoaderTestRunner类时,使用的自定义的类加载器(也就是SystemClassLoader的子加载器)。加载ClassLoaderTestRunner类时,还见面加载其父类,也便是Object类和Runable接口。

 

3)这个测试执行的长河:

    (1) 创建一个自定义加载器实例,指定其父加载器为系统加载器。

    (2) 加载类ClassLoaderTestRunner。

    (3) 启动一个线程执行相关任务。

 

4)根据上述所说,如果拿Object task = myAppClassLoader .loadClass(
classFullName) . newInstance();

改为:

ClassLoaderRunner task= (ClassLoaderRunner) myAppClassLoader. loadClass(
classFullName ) . newInstance();就会拧。

ClassLoaderRunner
是系加载器加载的,myAppClassLoader是一个自定义加载器。所以两者不可知开展路的更换。

 如果一直以是看似中采取于定义类加载器来加载Person类,也会见出现谬误。

 

 

 如果起趣味的话,可以依据我上面总结的情节,已经自己之这个测试,自己分析一下子线程t执行进程中,哪些类是叫打定义的接近加载器加载的,哪些类是为网加载器加载的,上述task执行的结果是啊?

 

如起无亮堂的呢可以参见:

参考

http://blog.csdn.net/irelandken/article/details/7048817

http://tyrion.iteye.com/blog/1958814

http://www.blogjava.net/lihuaxajh/articles/94371.html

http://www.javaworld.com/article/2077332/core-java/get-a-load-of-that-name.html

http://www.javaworld.com/article/2075796/java-platform/java-101–class-and-object-initialization.html

 

相关文章