中文JAVA技术平等自由协作创造

Java专题文章博客和开源

常用链接

统计

最新评论

Java类加载器classLoader的工作机制

  类加载器就是寻找类或接口字节码文件进行解析并构造JVM内部对象表示的组件。在Java中,类转载器把一个类装入JVM中,需要经过以下步骤:
  1.装载:查找和导入Class文件;
  2.链接: 执行校验、准备和解析步骤,其中解析步骤是可以选择的:
  a)校验: 检查载入Class文件数据的正确性;
  b)准备:给类的静态变量分配存储空间;
  c)解析:将符号引用变成直接引用sat答案
  3.初始化:对类的静态变量、静态代码块进行初始化工作。
  类装载工作是由ClassLoader及其之类负责的,ClassLoader是一个重要的Java运行时系统组件,它负责在运行时查找和装入Class字节文件。JVM在运行时会产生三个ClassLoader:跟装载器、ExtClassLoader(扩展类装载器)和AppClassLoader(系统类装载器)。其中,跟装载器不是ClassLoader的子类,它使用C++编写,因此我们在Java中看不到它,跟装载器负责装载JRE的核心类库,如rt.jar,charsets.jar等。ExtClassLoader和AppClassLoader都是ClassLoader的子类。其中ExtClassLoader负责装载JRE扩展目录ext中的JAR类包;AppClassLoader负责装载ClassPath路径下的类包托福答案
  这三个类装载器之间存在父子层级关系,跟装载器是ExtClassLoader的父装载器,ExtClassLoader是AppClassLoader的父装载器。默认情况下,使用AppClassLoader装载应用程序的类,我们可以试验如下:
  [java]
  package com.uestc.test;
  public class ClassLoaderTest {
  public static void main(String[] args) {
  ClassLoader c=Thread.currentThread()。getContextClassLoader();
  System.out.println(c);
  System.out.println(c.getParent());
  System.out.println(c.getParent()。getParent());
  }
  }
  运行结果如下:
  [java]
  sun.misc.Launcher$AppClassLoader@1016632
  sun.misc.Launcher$ExtClassLoader@dc6a77
  null
  从上述结果可以分析得出当前的ClassLoader是AppClassloader,父ClassLoader是ExtClassLoader,祖父ClassLoader是根类装载器,因为在Java中无法获得它的句柄,因此返回null.
  ClassLoader与Class.forName的区别
  classLoader中的函数loadclass用于Class文件的加载但并没有完成初始化工作,而使用Class.forName则完成了初始化工作即完成对类的静态变量、静态代码块执行初始化工作。实例如下:
  需要加载的类Reflect.java如下:
  [java]
  package com.uestc.test;
  public class Reflect {
  private int userName;
  private int password;
  static {
  System.out.println("Reflect static block");
  }
  public Reflect(){
  System.out.println("Reflect constructs");
  }
  public int getUserName() {
  return userName;
  }
  public void setUserName(int userName) {
  this.userName = userName;
  }
  public int getPassword() {
  return password;
  }
  public void setPassword(int password) {
  this.password = password;
  }
  }

  测试类Test.java如下:
  [java]
  package com.uestc.test;
  public class Test {
  public static void main(String[] args) {
  ClassLoader classLoader=Thread.currentThread()。getContextClassLoader();
  try {
  System.out.println("使用ClassLoader中的loadClass加载:");
  classLoader.loadClass("com.uestc.test.Reflect");
  System.out.println("使用Class.forName()加载:");
  Class.forName("com.uestc.test.Reflect");
  } catch (ClassNotFoundException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
  }
  }
  }
  运行结果如下:
  [java]
  使用ClassLoader中的loadClass加载:
  使用Class.forName()加载:
  Reflect static block
  从上述结果可以看出loadClass并没有进行初始化工作,而Class.forName()进行了初始化工作。

posted on 2013-12-01 20:26 好不容易 阅读(186) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航:
 
PK10开奖 PK10开奖