Java基础—ClassLoader的理解

发表于:2014-9-05 10:52

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:zhanjindong    来源:51Testing软件测试网采编

  默认的三个类加载器
  Java默认是有三个ClassLoader,按层次关系从上到下依次是:
  Bootstrap ClassLoader
  Ext ClassLoader
  System ClassLoader
  Bootstrap ClassLoader是最顶层的ClassLoader,它比较特殊,是用C++编写集成在JVM中的,是JVM启动的时候用来加载一些核心类的,比如:rt.jar,resources.jar,charsets.jar,jce.jar等,可以运行下面代码看都有哪些:
  URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
  for (int i = 0; i < urls.length; i++) {
  System.out.println(urls[i].toExternalForm());
  }
  其余两个ClassLoader都是继承自ClassLoader这个类。Java的类加载采用了一种叫做“双亲委托”的方式(稍后解释),所以除了Bootstrap ClassLoader其余的ClassLoader都有一个“父”类加载器, 不是通过集成,而是一种包含的关系。
  //ClassLoader.java
  public abstract class ClassLoader {
  ...
  // The parent class loader for delegation
  private ClassLoader parent;
  ...
  “双亲委托”
  所谓“双亲委托”就是当加载一个类的时候会先委托给父类加载器去加载,当父类加载器无法加载的时候再尝试自己去加载,所以整个类的加载是“自上而下”的,如果都没有加载到则抛出ClassNotFoundException异常。
  上面提到Bootstrap ClassLoader是最顶层的类加载器,实际上Ext ClassLoader和System ClassLoader就是一开始被它加载的。
  Ext ClassLoader称为扩展类加载器,负责加载Java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/目录下的所有的jar(包括自己手动放进去的jar包)。
  System ClassLoader叫做系统类加载器,负责加载应用程序classpath目录下的所有jar和class文件,包括我们平时运行jar包指定cp参数下的jar包。
  运行下面的代码可以验证上面内容:
  ClassLoader loader = Debug.class.getClassLoader();
  while(loader != null) {
  System.out.println(loader);
  loader = loader.getParent();
  }
  System.out.println(loader);
  “双亲委托”的作用
  之所以采用“双亲委托”这种方式主要是为了安全性,避免用户自己编写的类动态替换Java的一些核心类,比如String,同时也避免了重复加载,因为JVM中区分不同类,不仅仅是根据类名,相同的class文件被不同的ClassLoader加载就是不同的两个类,如果相互转型的话会抛java.lang.ClassCaseException.
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号