java类的装载(一)
来源:优易学  2009-12-4 10:13:43   【优易学:中国教育考试门户网】   资料下载   IT书店
文章页内部300*250广告位

  最近在研究osgi,在osgi里面里面有个很重要的东西,就是ClassLoader,所以,在网上搜集了一些资料,整理一下,

  并加入了自己的一些理解;

  (1)jvm的装载过程以及装载原理

  所谓装载就是寻找一个类或是一个接口的二进制形式并用该二进制形式来构造代表这个类或是这个接口的class对象的过程,

  其中类或接口的名称是给定了的。当然名称也可以通过计算得到,但是更常见的是通过搜索源代码经过编译器编译后所得到

  的二进制形式来构造。 在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化,

  其中链接又可以分成校验、准备和解析三步,除了解析外,其它步骤是严格按照顺序完成的,各个步骤的主要工作如下:

  装载:查找和导入类或接口的二进制数据;

  链接:执行下面的校验、准备和解析步骤,其中解析步骤是可以选择的;

  校验:检查导入类或接口的二进制数据的正确性;

  准备:给类的静态变量分配并初始化存储空间;

  解析:将符号引用转成直接引用;

  初始化:激活类的静态变量的初始化Java代码和静态Java代码块。

  (2):java中的类是什么?

  一个类代表要执行的代码,而数据则表示其相关状态。状态时常改变,而代码则不会。当我们将一个特定的状态与一个类相对应起来,也就意味着将一个类事例化。尽管相同的类对应的实例其状态千差万别,但其本质都对应着同一段代码。在JAVA中,一个类通常有着一个.class文件,但也有例外。在 JAVA的运行时环境中(Java runtime),每一个类都有一个以第一类(first-class)的Java对象所表现出现的代码,其是java.lang.Class的实例。我们编译一个JAVA文件,编译器都会嵌入一个public, static, final修饰的类型为java.lang.Class,名称为class的域变量在其字节码文件中。因为使用了public修饰,我们可以采用如下的形式对其访问:

  java.lang.Class klass = Myclass.class;

  一旦一个类被载入JVM中,同一个类就不会被再次载入了(切记,同一个类)。这里存在一个问题就是什么是“同一个类”?正如一个对象有一个具体的状态,即标识,一个对象始终和其代码(类)相关联。同理,载入JVM的类也有一个具体的标识,我们接下来看。

  在Java中,一个类用其完全匹配类名(fully qualified class name)作为标识,这里指的完全匹配类名包括包名和类名。但在JVM中一个类用其全名和一个加载类ClassLoader的实例作为唯一标识。因此,如果一个名为Pg的包中,有一个名为Cl的类,被类加载器KlassLoader的一个实例kl1加载,Cl的实例,即C1.class在JVM中表示为 (Cl, Pg, kl1)。这意味着两个类加载器的实例(Cl, Pg, kl1) 和 (Cl, Pg, kl2)是不同的,被它们所加载的类也因此完全不同,互不兼容的。那么在JVM中到底有多少种类加载器的实例?下一节我们揭示答案。

  (3):java的几种ClassLoader:

  在java中,我们可以取得这么以下三个ClassLoader类:

  一.    ClassLoader基本概念

  1.ClassLoader分类

  类装载器是用来把类(class)装载进JVM的。

  JVM规范定义了两种类型的类装载器:启动内装载器(bootstrap)和用户自定义装载器(user-defined class loader)。

  JVM在运行时会产生三个ClassLoader:Bootstrap ClassLoader、Extension ClassLoader和AppClassLoader。Bootstrap是用C++编写的,我们在Java中看不到它,是null,是JVM自带的类装载器,用来装载核心类库,如java.lang.*等。

  AppClassLoader的Parent是ExtClassLoader,而ExtClassLoader的Parent为Bootstrap ClassLoader。

  Java提供了抽象类ClassLoader,所有用户自定义类装载器都实例化自ClassLoader的子类。 System Class Loader是一个特殊的用户自定义类装载器,由JVM的实现者提供,在编程者不特别指定装载器的情况下默认装载用户类。系统类装载器可以通过 ClassLoader.getSystemClassLoader() 方法得到。

  例1,测试你所使用的JVM的ClassLoader

  /*LoaderSample1.java*/

  public   class  LoaderSample1 {

  public   static   void  main(String[] args) {

  Class c;

  ClassLoader cl;

  cl  =  ClassLoader.getSystemClassLoader();

  System.out.println(cl);

  while  (cl  !=   null ) {

  cl  =  cl.getParent();

  System.out.println(cl);

  }

  try  {

  c  =  Class.forName( " java.lang.Object " );

  cl  =  c.getClassLoader();

  System.out.println( " java.lang.Object's loader is  "   +  cl);

  c  =  Class.forName( " LoaderSample1 " );

  cl  =  c.getClassLoader();

  System.out.println( " LoaderSample1's loader is  "   +  cl);

  }  catch  (Exception e) {

  e.printStackTrace();

  }

  }

  }

  在我的机器上(Sun Java 1.4.2)的运行结果

  sun.misc.Launcher$AppClassLoader@1a0c10f

  sun.misc.Launcher$ExtClassLoader@e2eec8

  null

  java.lang.Object's loader is null

  LoaderSample1's loader is sun.misc.Launcher$AppClassLoader@1a0c10f

  第一行表示,系统类装载器实例化自类sun.misc.Launcher$AppClassLoader

  第二行表示,系统类装载器的parent实例化自类sun.misc.Launcher$ExtClassLoader

  第三行表示,系统类装载器parent的parent为bootstrap

  第四行表示,核心类java.lang.Object是由bootstrap装载的

  第五行表示,用户类LoaderSample1是由系统类装载器装载的

[1] [2] 下一页

责任编辑:小草

收藏此页】【 】【打印】【回到顶部
等级考试课程列表页595*300
文章搜索:
 相关文章
计算机底部580*90广告
文章页右侧第一330*280广告
计算机文章页资讯推荐
热点资讯
文章页330尺寸谷歌广告位
资讯快报
热门课程培训