java类加载

注:此为个人学习笔记,内容可能有些混乱,仅供参考。

 

1、  概览                             

因为类加载器 Java 类如同其它的 Java 类一样,也是要由类加载器来加载的。一般来说,开发人员编写的类加载器的父类加载器是系统类加载器。类加载器通过这种方式组织起来,形成树状结构。树的根节点就是引导类加载器。

 

2、  系统提供的类加载器

主要有下面三个:

·  引导类加载器 (bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自  java.lang.ClassLoader

·  扩展类加载器 (extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。

·  系统类加载器 (system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过  ClassLoader.getSystemClassLoader() 来获取它。

 

代码段:

package  xjt.classloader;

 

public   class  ClassLoaderTree {

     public   static   void  main(String[] args) { 

        ClassLoader loader = ClassLoaderTree. class .getClassLoader(); 

         /**

          *   第一个输出的是   ClassLoaderTree类的类加载器,即系统类加载器。

          *   它是   sun.misc.Launcher$AppClassLoader类的实例;

          *   第二个输出的是扩展类加载器,是   * sun.misc.Launcher$ExtClassLoader类的实例。

          *   需要注意的是这里并没有输出引导类加载器,

          *   这是由于有些   JDK   的实现对于 父类加载器是引导类加载器的情况,

         * getParent()方法返回  null

          *   */

         while  (loader !=  null ) { 

            System. out .println(loader.toString()); 

            loader = loader.getParent(); 

        } 

    }

}

 

3、 类加载器的代理模式

类加载器在尝试自己去查找某个类的字节代码并定义它时, 会先代理给其父类加载器,由父类加载器先去尝试加载这个类 ,依次类推。在介绍代理模式 背后的动机之前,首先需要说明一下 Java 虚拟机是 如何判定两个 Java 类是相同的 。Java 虚拟机不仅要看类的 全名是否相同 ,还要看加载此类的 类加载器是否一样 。只有两者都相同的情况,才认为两个类是相同的。

 

4、  加载类的过程

真正完成类的加载工作是通过调用  defineClass 来实现的;而启动类的加载过程是通过调用  loadClass 来实现的。

方法  loadClass() 抛出的是  java.lang.ClassNotFoundException 异常;

方法  defineClass() 抛出的是  java.lang.NoClassDefFoundError 异常。

遇到  ClassNotFoundException 和  NoClassDefFoundError 等异常的时候,应该检查抛出异常的类的类加载器和当前线程的上下文类加载器

 

5、 Class.forName

Class.forNameClass.forName 的一个很常见的用法是在加载数据库驱动的时候。如  Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance() 用来加载 Apache Derby 数据库的驱动。是一个静态方法,同样可以用来加载类。

 

6、 类加载器与 Web  容器

对于运行在 Java EE™容器中的 Web 应用来说,类加载器的实现方式与一般的 Java 应用 有所不同 。不同的 Web 容器的实现方式也会有所不同。以 Apache Tomcat 来说, 每个 Web 应用都有一个对应的类加载器实例 。该类加载器也使用代理模式,所不同的是它是 首先尝试去加载某个类 ,如果找不到再代理给父类加载器。这与一般类加载器的顺 序是相反的。这是 Java Servlet 规范中的推荐做法,其目的是使得  Web 应用自己的类的优先级高于 Web 容器提供的类 。这种代理模式的一个例外是: Java 核心库的类是不在查找范围之内 的。这也是为了保证 Java 核心库的类型安全。

 

7、 OSGi Open Service Gateway Initiative 是 Java 上的动态模块系统。

OSGi 中的每个模块(bundle)都包含 Java 包和类。模块可以声明它所依赖的需要导入(import)的其它模块的 Java 包和类(通过  Import-Package ),也可以声明导出(export)自己的包和类,供其它模块使用(通过  Export-Package )。也就是说需要能够隐藏和共享一个模块中的某些 Java 包和类。这是通过 OSGi 特有的类加载器机制来实现的。 OSGi 中的每个模块都有对应的一个类加载器。

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值