from: http://blog.bcchinese.net/shiaohuazhang/archive/2004/10/13/2715.aspx
1.类装载器的功能及分类
功能:类装载器是用来把类(class)装载进JVM的
分类:启动内装载器(bootstrap)和用户自定义装载器(user-defined class loader)。
1)bootstrap是JVM自带的类装载器,用来装载核心类库,如java.lang.*等。由例1可以看出,java.lang.Object是由bootstrap装载的。
2). 扩展(extensions)类加载器,扩展类加载器负责加载扩展路径下的代码,一般位于<JAVA_HOME>/jre/lib/ext 或者通过java.ext.dirs 这个系统属性指定的路径下的代码。这个类加载器是由sun.misc.Launcher$ExtClassLoader 实现的。
3)System Class Loader是一个特殊的用户自定义类装载器,由JVM的实现者提供,
在编程者不特别指定装载器的情况下默认装载用户类。
系统类装载器可以通过ClassLoader.getSystemClassLoader() 方法得到。
4)用户自定义的Class Loader,继承ClassLoader.
bootstrap<---ExtClassLoader<---AppClassLoader (父子关系)
======================
例1,测试你所使用的JVM的ClassLoader
package com.test.app;
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.6)的运行结果
sun.misc.Launcher$AppClassLoader@19821f
sun.misc.Launcher$ExtClassLoader@addbf1
null
java.lang.Object's loader is null
LoaderSample1's loader is sun.misc.Launcher$AppClassLoader@19821f
第一行表示,系统类装载器实例化自类sun.misc.Launcher$AppClassLoader
第二行表示,系统类装载器的parent实例化自类sun.misc.Launcher$ExtClassLoader
第三行表示,系统类装载器parent的parent为bootstrap
第四行表示,核心类java.lang.Object是由bootstrap装载的
第五行表示,用户类LoaderSample1是由系统类装载器装载的
============================
2.parent delegation模型
从1.2版本开始,Java引入了双亲委托模型,从而更好的保证Java平台的安全。
在此模型下,当一个装载器被请求装载某个类时,它首先委托自己的parent去装载,
若parent能装载,则返回这个类所对应的Class对象,若parent不能装载,则由parent的请求者去装载。
自己写的加载器类的父类是AppClassLoader
![](http://dl.iteye.com/upload/attachment/215524/b6cccbec-fa58-3a93-8f1e-d15a6b52361d.jpg)
3.命名空间及其作用
每个类装载器有自己的命名空间,命名空间由所有以此装载器为创始类装载器的类组成。
不同命名空间的两个类是不可见的,但只要得到类所对应的Class对象的reference,还是可以访问另一命名空间的类。
=============================
package com.test.app;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLClassLoader;
public class LoaderSample2 {
public static void main(String[] args) {
try {
String path = System.getProperty("user.dir");
URL[] us = {new URL("file://" + path + "/subapp/")};
ClassLoader loader = new URLClassLoader(us);
Class c = loader.loadClass("com.test.app.subapp.LoaderSample3");
Object o = c.newInstance();
Field f = c.getField("age");
int age = f.getInt(o);
System.out.println("age is " + age);
} catch (Exception e) {
e.printStackTrace();
}
}
}
===============
package com.test.app.subapp;
public class LoaderSample3 {
static {
System.out.println("LoaderSample3 loaded");
}
public int age = 30;
}
====================
4.运行时包(runtime package)
由同一类装载器定义装载的属于相同包的类组成了运行时包,决定两个类是不是属于同一个运行时包,
不仅要看它们的包名是否相同,还要看的定义类装载器是否相同。只有属于同一运行时包的类才能互相访问包可见的类和成员。
这样的限制避免了用户自己的代码冒充核心类库的类访问核心类库包可见成员的情况。假设用户自己定义了一个类java.lang.Yes,
并用用户自定义的类装载器装载,由于java.lang.Yes和核心类库java.lang.*由不同的装载器装载,它们属于不同的运行时包,
所以java.lang.Yes不能访问核心类库java.lang中类的包可见的成员。
5.类的更新
类被加载后,但是又发生了修改,被重新编译了。是否原来的类能从加载器中删除?比如jsp变化了,服务端JVM需要更新这个类。但是其实是弄出一个新的加载器实例来加载这个class文件。至于什么时候卸载旧的class文件则由JVM自己来处理。
6.动态加载
//具体的类名可以是从配置文件读取的,这样就实现了动态的加载,修改配置文件就可以加载不同的实现类,
//必须重新编译类,newInstance: 弱类型。低效率。只能调用无参构造。
Class c=Class.forName("fromXmljavaname").newInstance();
//通过反射机制可以实现复杂一些的类的动态加载
Class c=Class.forName("fromXmljavaname").
//通过反射调用类的getInstance完成实例化
Method m=c.getMethod("getInstance", String.class);
Test t=(Test)m.invoke(null, "abc");//getInstance是static,应该第一个参数为null,否则需要被调类的实例对象
总结:
简单讨论了类装载器,parent delegation模型,命名空间,运行时包.
命名空间并没有完全禁止属于不同空间的类的互相访问,双亲委托模型加强了Java的安全,运行时包增加了对包可见成员的保护。
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0021/5524/b6cccbec-fa58-3a93-8f1e-d15a6b52361d-thumb.jpg)
- 大小: 42.7 KB
分享到:
相关推荐
Java的类装载器分为两大类:启动类装载器(Bootstrap ClassLoader)和用户自定义装载器(User-Defined Class Loader)。 - **启动类装载器**:由JVM自身实现,主要负责加载JDK的核心类库,如rt.jar中的java.lang.*...
类装载器(Class Loader)是Java虚拟机(JVM)的核心组成部分之一,负责将类文件加载到JVM中,以便它们可以被执行。在Java中,每个类都是由类装载器加载到JVM中的,并且每个类都由特定的类装载器实例加载。类装载器...
Java中的所有类都必须先被装载到JVM中才能被执行,这个过程由JVM内的类装载器(ClassLoader)来完成。类装载器的工作是将类文件从硬盘读取到内存中,使得JVM能够识别和执行这些类。 Java类大致分为三类:系统类、...
3. **应用程序类装载器(Application Class Loader)**:它是默认的应用程序类装载器,负责加载用户类路径(`java.class.path`)中定义的类。用户可以通过环境变量`CLASSPATH`来控制哪些类路径被包含在内。应用程序类...
Java中的类必须被装载到JVM中才能运行,这一过程由JVM中的类装载器(Class Loader)完成。类装载器的主要职责是从文件系统或网络中读取类文件,将其转换为JVM可识别的字节码格式,并将其加载到内存中,进而创建类的...
- **启动类装载器(Bootstrap Class Loader)**:这是系统级的类装载器,用于装载Java的核心类库,如`java.lang.*`等,它是所有其他类装载器的父类装载器。 - **扩展类装载器(Extension Class Loader)**:用于装载扩展...
JVM加载class文件的原理机制是Java中的核心机制之一,由于Java中的所有类必须被装载到JVM中才能运行,这个装载工作是由JVM中的类装载器完成的。类装载器所做的工作实质是把类文件从硬盘读取到内存中。 类加载机制 ...
JVM规范定义了两种类型的类装载器:启动类装载器(bootstrap)和用户自定义装载器(user-defined class loader)。JVM在运行时会产生3个类加载器组成的初始化加载器层次结构。 * 引导类加载器(Bootstrap ClassLoader)...
2. **扩展类装载器(Extension Class Loader)**:由`sun.misc.Launcher$ExtClassLoader`实现,负责加载扩展目录`$JAVA_HOME/jre/lib/ext`下的jar包。 3. **应用类装载器(Application Class Loader)**:也称为...
JVM主要包括类装载器(Class Loader)、运行时数据区(Runtime Data Area)、执行引擎、本地方法接口(Native Method Interface)和本地库。其中,类装载器负责加载类文件,确保程序能够正确运行;运行时数据区则...
装载过程是由类加载器(Class Loader)完成的,类加载器分为应用程序类加载器(Application Class Loader)、扩展类加载器(Extension Class Loader)和引导类加载器(Bootstrap Class Loader)。每个类加载器都有特定的任务...
在Java虚拟机(JVM)中,类装载器(Class Loader)扮演着极其重要的角色,它的主要职责是根据给定的全限定类名(Fully Qualified Class Name)来加载类的二进制流到JVM内存中。JVM规范定义了两类主要的类装载器: 1. **...
- **类加载机制**:Java程序运行前,JVM会通过类加载器(Class Loader)将Java源代码编译成的字节码文件加载到内存中。类加载过程主要包括加载(Loading)、验证(Verification)、准备(Preparation)、解析...
类的加载过程涉及Bootstrap Loader(启动类装载器)、ExtClassLoader(扩展类装载器)和AppClassLoader(应用程序类装载器)。Bootstrap Loader负责加载JDK目录下的类库,ExtClassLoader加载系统类路径指定的类库,...
Java采用了委托模型机制,这个机制简单来讲,就是“类装载器有载入类的需求时,会先请示其Parent使用其搜索路径帮忙载入,如果Parent 找不到,那么才由自己依照自己的搜索路径搜索类”。 类加载器的委托模型 这个...
1. **类装载器(Class Loader)**:负责加载Java类到JVM中,这个过程包括加载、验证和准备三个步骤。类装载器按照双亲委托模型工作,确保类的唯一性。 2. **运行数据区(Runtime Data Areas)**:包括程序计数器、...
- **装载(Load)**:类加载器从指定位置(如硬盘、网络等)找到 `.class` 文件,并将其读入内存,形成一个类的二进制数据。 - **验证(Verify)**:确保被加载的类符合Java虚拟机规范,防止恶意代码对系统的破坏。 ...
1. 类装载器(Class loader)子系统:它的主要任务是根据类的全限定名(如`java.lang.Object`)加载对应的.class文件内容到运行时数据区域的方法区。Java程序员可以继承`java.lang.ClassLoader`来定制自己的类装载器...
1. 类装载器(Class Loader):负责加载类文件,将二进制数据转化为Java对象。分为引导类装载器、扩展类装载器和应用程序类装载器,它们遵循双亲委托模型进行工作。 2. 运行时数据区(Runtime Data Area):包括...