android 插件开发前凑java类加载器

我们在写java源代码,要通过jvm虚拟机才能运行跑起来,我们知道在jdk安装目录的bin目录下有javac,exe,这个就是编译,把.java文件编译成.class文件,然后通过java.exe把.class运气在jvm虚拟机中,也就是类加载的过程,java有多种类加载器,我们写个demo,演示下

package com.demo;
public class ClassLoaderTest {
   public static void main(String[] args){  
       //打印出类加载器的名称
       System.out.println("ClassLoaderText类的加载器的名称:"+ClassLoaderTest.class.getClassLoader().getClass().getName());  
   }  
}

-----------------------------打印结果-----------------------------------

ClassLoaderText类的加载器的名称:sun.misc.Launcher$AppClassLoader

我们发现是Launcher类中的内部类AppClassLoader去加载的,ClassLoaderTest类是我们自己写的,那么我现在去使用第三方jar包中的类试试,我引入了gson.jar,google出的解析json的jar,

package com.demo;
import com.google.gson.Gson;
public class ClassLoaderTest {
   public static void main(String[] args){  
       //打印出类加载器的名称
       System.out.println("Gson类的加载器的名称:"+Gson.class.getClassLoader().getClass().getName());  
   }  
}

------------------------------打印结果---------------------------------------

Gson类的加载器的名称:sun.misc.Launcher$AppClassLoader

发现其实也是用AppClassLoader类加载器去加载,但是我们很好奇,类加载器也是java类,那么谁或者那个类加载器去加载这些java类的加载器呢?而且这个类加载器肯定不是用java写的,答案是BootStrap这个类加载器,它是由C++编写的,已经封装到JVM内核中了,除了AppClassLoader还有一个ExtClassLoader类也是用java写的类加载器,只是和AppClassLoader加载的情况不同,当然我们也可以自定义类加载器,现在看下这几个类加载器的职责:该图来自http://blog.csdn.net/gjanyanlig/article/details/6818655博客,在这表示谢谢

android 插件开发前凑java类加载器_第1张图片

ExtensionClassLoader类加载器是加载如图中的类的:

android 插件开发前凑java类加载器_第2张图片

而BootStrapClassLoader类加载器是加载rt.jar中的类,如图:

android 插件开发前凑java类加载器_第3张图片

我们现在随意拿这些包里的一个类看看它的类加载是啥,

package com.demo;
import java.util.List;
public class ClassLoaderTest {
   public static void main(String[] args){  
       //打印出类加载器的名称
       System.out.println("Gson类的加载器的名称:"+List.class.getClassLoader());  
   }  
}

-------------------------------打印结果是-------------------

List类的加载器的名称:null

为什么是null呢?

因为List这样的系统提供jar类都在rt.jar中,所以由BootStrap类加载器加载,因为BootStrap是祖先类,不是Java编写的,所以打印出class为null

还有一个问题就是AppClassLoader和ExtensionClassLoader有关关系没有,通过代码我们就知道

package com.demo;
public class ClassLoaderTest {
   public static void main(String[] args){  
       //打印出类加载器的名称
       System.out.println("ClassLoaderTest类的加载器的名称:"+ClassLoaderTest.class.getClassLoader().getClass().getName());  
       ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
       if(classLoader!=null){
        ClassLoader parent = classLoader.getParent();
        System.out.println("parent-->"+parent);
       }
   }  
}

-----------------------------打印结果--------------------------

ClassLoaderTest类的加载器的名称:sun.misc.Launcher$AppClassLoader
parent-->sun.misc.Launcher$ExtClassLoader@41bf9980

发现其实Java虚拟机中的所有类加载器采用具有父子关系的树形结构进行组织,在实例化每个类加载器对象的时候,需要为其指定一个父级类加载器对象或者默认采用系统类加载器为其父级类加载




你可能感兴趣的:(android 插件开发前凑java类加载器)