当前位置: 首页 > 科技观察

热门推荐:深入理解Java类加载器

时间:2023-03-19 21:34:19 科技观察

先回顾下,java虚拟机加载java类的步骤:java文件编译成字节码文件(.)读取.class文件,转换成java实例.lang.Class,***通过newInstance方法创建这个类的一个对象。ClassLoader的作用是根据一个类名找到对应的字节码,根据这些字节码定义对应的类,它是java.lang.Class的一个实例。类加载器的组织结构Java有3个初始类加载器。当java虚拟机启动时,它们会按照以下顺序启动:Bootstrapclassloader->extensionclassloader->systemclassloader。三者的关系:引导类加载器是扩展类加载器的父类,扩展类加载器是系统类加载器的父类。bootstrap类加载器是最原始的类加载器,不是java代码写的,而是native代码写的。Java具有一次编译,全平台运行的效果,因为它为不同的平台编写了一个功能相同但用不同语言实现的底层代码。它负责加载java核心库。您可以运行以下代码来查看本地Java核心库的位置:URL[]urls=sun.misc.Launcher.getBootstrapClassPath().getURLs();for(inti=0;iloadClass(Stringname,booleanresolve)throwsClassNotFoundException{//首先checkiftheclasshasalreadybeenloadedClassc=findLoadedClass(name);if(c==null){try{if(parent!=null){//从父加载器加载c=parent.loadClass(name,false);}else{//从引导加载器加载c=findBootstrapClassOrNull(name);}}catch(ClassNotFoundExceptione){//ClassNotFoundExceptionthrownifclassnotfound//fromthenon-nullparentclassloader}if(c==null){//Ifstillnotfound,theninvokefindClassinorder//findtheclass.c=findClass(name);}}if(resolve){resolveClass(c);}returnc;}比如类加载器加载类A的过程:1、判断是否已经加载,在缓存中查找,如果是则跳到7;否则,进行下一步2,判断当前加载器是否有父加载器,如果没有,则当前类加载器为extclassloader,跳至4;否则,下一步3,请求父加载器加载该类,如果加载成功,则跳过7;如果不成功,即父加载器找不到class,跳过24,请求jvm的bootstrapclassloader加载,如果加载成功,跳过7;如果失败,则跳过55。当前加载程序自行加载。如果成功,则跳转到7;否则跳转到66,抛出ClassNotFoundException7,返回Class。Java自己写类加载器加载类的过程本质上就是调用loadClass()方法,在loadClass()方法中调用findLoadedClass检查类是否已经加载,如果没有就调用父加载器的loadClass(),如果父加载器无法加载该类,调用findClass()查找该类。那么我们要做的就是新建一个MyClassLoader来继承java.lang.ClassLoader,并重写其中的findClass()方法。主要是重新设计了查找字节码文件的scheme,然后调用definedClass返回。我写了一个demo,使用自己的类加载器加载指定的java文件,有热部署效果,具体请查看以下网址。演示地址:http://git.oschina.net/ericquan8/hot-deploy