黑马程序员技术交流社区

标题: 关于类加载器 [打印本页]

作者: 黑马王冬冬    时间: 2012-7-25 15:24
标题: 关于类加载器
  1. package com.itheima;

  2. public class ClassLoaderTest {
  3.         public static void main(String[] args){
  4.                 System.out.println(
  5.                 ClassLoaderTest.class.getClassLoader().getClass().getName() //位置1
  6.                 +"\n"+System.class.getClassLoader());
  7.                
  8.                 ClassLoader loader = ClassLoaderTest.class.getClassLoader();
  9.                 while(loader != null) {
  10.                         System.out.println(loader.getClass().getName());//位置2
  11.                         loader = loader.getParent();
  12.                 }
  13.                 System.out.println(loader);
  14.         }
  15.                 }
复制代码
输出结果是,
sun.misc.Launcher$AppClassLoader
null
sun.misc.Launcher$AppClassLoader
sun.misc.Launcher$ExtClassLoader
null
我的疑问是在位置1和位置2,为何ClassLoaderTest.class.getClassLoader()最后的输出结果分别为sun.misc.Launcher$AppClassLoader和sun.misc.Launcher$AppClassLoader,sun.misc.Launcher$ExtClassLoader?为何多出一个sun.misc.Launcher$ExtClassLoader?




作者: 张莹莹    时间: 2012-7-25 23:41
ClassLoader它就是用来加载Class文件到JVM,以供程序使用的。
bootstrap classloader(启动类加载器)是用C语言所编写的,没有对应的java Object,而是JVM实现的一部分,。
这个ClassLoader在JVM运行的时候加载java核心的API以满足java程序最基本的需求,其中就包括用户定义的ClassLoader。用户定义
是指通过java程序实现的ClassLoader,一个是ExtClassLoader,这个ClassLoader是用来加载java的扩展API的,也就是/lib/ext中
的类,一个是AppClassLoader,这个ClassLoader是用来加载用户机器上CLASSPATH设置目录中的Class的,通常在没有指定
ClassLoader的情况下,程序员自定义的类就由该ClassLoader进行加载。

1.ClassLoaderTest.class.getClassLoader().getClass().getName()是获取ClassLoaderTest.class类加载器的名字,即
AppClassLoader(加载class的)。
2.System.class.getClassLoader() 输出为null, 这是因为AppClassLoader的父加载器虽然是ExtClassLoader,但是却是Bootstrap
加载的(所以它的.getClassLoader()返回为null)
3.ClassLoader loader = ClassLoaderTest.class.getClassLoader();
  loader.getClass().getName()
当运行一个程序的时候,JVM启动,运行bootstrap classloader,该ClassLoader加载java核心API(ExtClassLoader和
AppClassLoader也在此时被加载),然后调用ExtClassLoader加载扩展API,最后AppClassLoader加载CLASSPATH目录下定义的Class
,这就是一个程序最基本的加载流程。
所以打印出sun.misc.Launcher$AppClassLoader,sun.misc.Launcher$ExtClassLoader
4.最后loader = loader.getParent();再次去获取bootstrap classloader即启动加载器的对象则得到null.
来段形象的解释:
Bootstrap是爷爷、ExtClassLoader是爸爸、AppClassLoader是孩子(孙子)。但由于爸爸ExtClassLoader太忙了,所以照顾孩子
AppClassLoader的责任就有爷爷Bootstrap来处理了(即,虽然ExtClassLoader是AppClassLoader老爸,但却是由爷爷Bootstrap加载
的AppClassLoader。

代码举例见ClassLoader.png

ClassLoader.png (41.54 KB, 下载次数: 50)

类加载器

类加载器





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2