类加载器和类加载机制


一个jvm进程中的内存和其他进程之间不产生影响。
通常会有几种情况使jvm停止,.eg:exit(); runtime 等

一.类的加载:


当一个类加载到jvm内存中需要通常是连续的3个步骤:

将class文件加载到内存中, 并建立class 对象(java.lang.class )
是类加载的本意和最终状态。


1.加载:由类加载器进行加载,jvm提供类加载器,也可以通过继承classRoader实现自定义的类加载器。

2.连接:生成对应的class对象后就进入连接状态 把类的二进制数据加载到JRE中了。

(1).验证 加载类是否有正确的结构

(2).准备:给类的静态Field分配内存,初值

(3).解析:将类的二进制数据中符号应用换成直接引用

3.初始化:正常的类初始化,执行顺序。


二.类加载器:


class 对象 的唯一标识:(类名,包名,加载器名)

jvm 启动时会形成3层类加载器结构:  

1:Bootstarp ClassLoader 根加载,当执行java.exe命令时会 加载java内核不是Java.lang.ClassLoader的子类。不是由java语言实现的。

2: Extension ClassLoader 扩展类加载器,负责加载JRE的扩展目录下的Class JAR包下的类。

3: System ClassLoader 系统(应用)类加载器, jvm启动时加载classpath 路径下的包和类路径。 自定义的加载器以类加载器作为父加载器。

后两者 e是s的父类加载器,但没有继承关系。

系统类加载器的实例是APPClassLoader,扩展类加载器的实例是ExtClassLoader。 这两个类都是URLClassLoader类的实例。

三.类加载的机制


1.全盘负责: 一个类加载器负责加载某个Class时,该Class依赖的其他的class也由他加载,除非显示指明由其他加载。
2.父类委托:先让父类加载,如果父类无法加载,才尝试从自己的类路径中加载。当父类为null时,JVM内置的类(称为:bootstrap class loader)就会充当父类。
3.缓存机制:先在缓存区中找,不存在才读取转换。

四.自定义类加载器:


根据父类委托,若父类无法找到则调用当前加载器找,继承并重写classLoader中方法实现自定义类加载器,

loadClass()和findclass()方法。
事实上,只重写findClass可以避免父类委托和缓冲两种机制的覆盖。
同时该类还有一些无法覆写的方法,eg:defineClass 该方法用于将将类的字节码文字写入到byte[]数组中,并转化为class对象。

自定义加载器可以实现某些功能:eg:执行前检测签名。其实通过XML文档描述的配置信息最终都要变成Java类,实都是通过ClassLoader来完成的。

eg:

** 
     * 一、ClassLoader加载类的顺序 
     *  1.调用 findLoadedClass(String) 来检查是否已经加载类。 
     *  2.在父类加载器上调用 loadClass 方法。如果父类加载器为 null,则使用虚拟机的内置类加载器。 
     *  3.调用 findClass(String) 方法查找类。 
     * 二、实现自己的类加载器 
     *  1.获取类的class文件的字节数组 
     *  2.将字节数组转换为Class类的实例 
     * @author lei 2011-9-1 
     */  
    public class ClassLoaderTest {  
        public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {  
            //新建一个类加载器  
            MyClassLoader cl = new MyClassLoader("myClassLoader");  
            //加载类,得到Class对象  
            Class<?> clazz = cl.loadClass("classloader.Animal");  
            //得到类的实例  
            Animal animal=(Animal) clazz.newInstance();  
            animal.say();  
        }  
    }  
    class Animal{  
        public void say(){  
            System.out.println("hello world!");  
        }  
    }  
    class MyClassLoader extends ClassLoader {  
        //类加载器的名称  
        private String name;  
        //类存放的路径  
        private String path = "E:\\workspace\\Algorithm\\src";  
        MyClassLoader(String name) {  
            this.name = name;  
        }  
        MyClassLoader(ClassLoader parent, String name) {  
            super(parent);  
            this.name = name;  
        }  
        /** 
         * 重写findClass方法 
         */  
        @Override  
        public Class<?> findClass(String name) {  
            byte[] data = loadClassData(name);  
            return this.defineClass(name, data, 0, data.length);  
        }  
        public byte[] loadClassData(String name) {  
            try {  
                name = name.replace(".", "//");  
                FileInputStream is = new FileInputStream(new File(path + name + ".class"));  
                ByteArrayOutputStream baos = new ByteArrayOutputStream();  
                int b = 0;  
                while ((b = is.read()) != -1) {  
                    baos.write(b);  
                }  
                return baos.toByteArray();  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
            return null;  
        }  
    }  


五.URLClassLoader


URLClassLoader 是扩展和系统类加载器的父类。是ClassLoader的子类
作用:既可以本地获取二进制文件,也可以从远程主机获取二进制文件, 构造方法两种:
1:默认的父类加载器创建一个classLoader ,并从urls指定的路径获取
2:使用指定父类的加载器创建一个ClassLoader,得到URLClassLoader后就可调用loadClass 方法来加载指定的类了。
用法:
 URL   url   =   file.toURI().toURL(); 
  URLClassLoader   loader   =   new   URLClassLoader(new   URL[]   {   url   });   
  Class   tidyClazz   =   loader.loadClass(所需class的含包名的全名); 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值