类加载器

类加载器

类的加载时机有哪些?

    * 创建该类或子类的对象会触发类加载。
    * 访问类的静态成员变量时会触发类加载。
    * 调用类的静态方法时会触发类加载。
    * 使用java命名执行有main方法的类,也会触发类的加载
    * 使用Class类的forName方法也可以强制触发类的加载。

Class类的对象:在类加载的时候创建出来的,如果是使用反射技术,必须要先获得该Class对象。

什么是类加载器

一个负责加载类的对象。

类加载器的作用

将类的字节码文件从硬盘中加载到内存,并在内存中创建一个Class对象。
Class对象就是根据类的字节码文件创建出来的,该对象中包含了类中的所有信息:成员变量和成员方,构造方法等

类加载器的分类

引导类加载器:BootstrapClassLoader
         由C/C++语言编写的一个类 
         负责加载Java中基础jar里面的类,比如:rt.jar
扩展类加载器:ExtClassLoader
        由Java语言编写,是Java中的一个类    
        负责加载扩展包中的类
应用类加载器:AppClassLoader 
        由Java语言编写,是Java中的一个类 
        负责加载程序猿自己编写的类以及第三方jar中的类。
        ExtClassLoader和AppClassLoader都是ClassLoader的子类

如何获得类加载器对象

通过Class对象的getClassLoader方法获得。

类加载器间的关系

应用类加载器的父加载器是:扩展类加载器(ExtClassLoader)
扩展类加载器的父加载器是:引导类加载器(BootstrapClassLoader)
    * 并不是子父关系,是上下级关系。

类加载器常用方法

 ClassLoader getParent() 获得父加载器对象
 

 URL getResource(String name)
        * 根据资源文件名获得URL对象
        * 资源文件名是以 / 开头,表示从src目录下查找(本质是bin下查找)
     
        - URL:统一资源定位符
         http://www.baidu.com/image/a.png
         
        - URL类常用方法
         - String getPath(); 获得资源的绝对路径。     


InputStream getResourceAsStream(String name)
  - 根据资源文件名获得与该文件关联的字节输入流
  - 资源文件名是以 / 开头,表示从src目录下查找(本质是bin下查找)

  • 示例代码

public class ClassLoaderDemo02 {
    public static void main(String[] args) throws Exception {
        // 获得学生类的Class对象
        Class c = Student.class;
        // 根据资源文件名获得与该文件关联的字节输入流
        InputStream in = c.getResourceAsStream("/a.txt");
        System.out.println(in.read());
    }
    
    /**
     * URL getResource(String name)
     * @throws Exception
     */
    public static void test02() throws Exception {
        // 获得学生类的Class对象
        Class c = Student.class;
        
        // 根据资源文件名获得URL对象
        URL url = c.getResource("/a.txt");
        System.out.println(url.getPath());
        
        // 创建字节输出流
        FileInputStream fis = new FileInputStream(url.getPath());
        System.out.println(fis.read());
        fis.close();
    }
    
    /**
     * ClassLoader getParent() 获得父加载器对象
     * @throws ClassNotFoundException
     */
    public static void test01() throws ClassNotFoundException {
        // 获得学生类的Class对象
        Class c = Student.class;
        // 获得类加载器对象
        ClassLoader cl = c.getClassLoader();
        // sun.misc.Launcher$AppClassLoader@4e25154f
        System.out.println(cl);
        
        // 获得cl的父加载器对象
        ClassLoader clp = cl.getParent();
        // sun.misc.Launcher$ExtClassLoader@33909752
        System.out.println(clp);
        
        // 获得clp的父加载器对象
        ClassLoader clpp = clp.getParent();
        // null
        System.out.println(clpp);
        
        // 获得类加载器为null时:表示此类是引导类加载器负责加载的
        System.out.println(String.class.getClassLoader());
    }
}

类加载器加载机制:双亲委托机制

双亲委派模型的工作流程

- 如果一个类加载器收到了类加载的请求,
- 它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上,
- 因此,所有的类加载请求最终都应该被传递到顶层的启动类加载器中,
- 只有当父加载器在它的搜索范围中没有找到所需的类时,即无法完成该加载,
- 子加载器才会尝试自己去加载该类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值