`

Java的类加载器

阅读更多

1、类加载器负责将.class文件(可能在磁盘上,也可能在网络上)加载到内存中,并为之生成一个java.lang.Class对象。
  JVM在运行时会产生三个ClassLoader:根装载器、扩展类装载器(ExtClassLoader)、系统应用类装载器(AppClassLoader)。
  现分别对这几个类的装载器说明如下:
    (1)、根装载器(bootstrap class Loader):计算机本地语言所编写(汇编、C/C++),加载jre最核心的类,如JRE扩展目标下的rt.jar、charsets.jar...,如java.lang.String类;

import java.net.URL;

/**
 * @Description:根类加载器
 * @ClassName: BootStartTest
 * @Project: base-info
 * @Author: zxf
 * @Date: 2011-7-19
 */
public class BootStartTest {

	public static void main(String[] args) {
		URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
		// 遍历、输出根加载器加载的全部URL
		for (URL u : urls) {
			System.out.println(u.toExternalForm());
		}
	}
}

    (2)、扩展类装载器(extesion class loader):加载jre/lib/ext包里的jar类,如;
    (3)、系统应用类装载器(applicatioin class loader):负责加载classpath路径下的包类,通常是用户定义的类,也是系统默认的装载方式;

import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;

/**
 * @Description:
 * @ClassName: ClassLoaderProTest
 * @Project: base-info
 * @Author: zxf
 * @Date: 2011-7-19
 */
public class ClassLoaderProTest {

	public static void main(String[] args) throws IOException {
		ClassLoader sysClassLoader = ClassLoader.getSystemClassLoader();
		System.out.println("系统类加载器:" + sysClassLoader);

		// 系统类加载器加载的路径
		Enumeration<URL> enums = sysClassLoader.getResources("");
		while (enums.hasMoreElements()) {
			System.out.println(enums.nextElement());
		}
		ClassLoader extClassLoader = sysClassLoader.getParent();
		System.out.println("扩展类加载器:" + extClassLoader);
		System.out.println("扩展类加载器加载路径:" + System.getProperty("java.ext.dirs"));
		ClassLoader bootClassLoader = extClassLoader.getParent();
		System.out.println("根类加载器:" + bootClassLoader);
	}
}
 

2、JVM类加载机制主要有以下三种机制:

   (1)、全盘负责:所谓全盘负责就是当一个类加载器负责加载一个Class的时候,该Class所依赖和引用的Class类也将由该类加载器载入。除非显式的指定使用另外一个类加载器来载入。

   (2)、父类委托:所谓父类委托就是先让parent(父)类先加载器视图先加载该Class,只有当父类加载无法加载该Class类时,才尝试自己从类路径加载该Class类。

   (3)、缓存机制:缓存机制会保证每个被类加载器加载过的Class类都会被缓存,当程序使用某个Class类时,首先会去缓存中查找该Class类,只有当缓存中不存在该Class类时,系统才会读取该类对应的二进制数据,并将其转换成Class对象,并存入缓存。这就是我们修改了Class类,要重新启动JVM,所修改的程序才生效的原因。

 

3、创建并使用自定义类加载器:

     JVM中除了根加载器之外,其它加载器都是classLoader子类的实例。开发者可以通过扩展ClassLoader类的子类,并重写ClassLoader所包含的方法来实现自定义的类加载器。

/**
 * @Description:
 * @ClassName: A
 * @Project: base-info
 * @Author: zxf
 * @Date: 2011-5-25
 */
public class A {
	public String print(String n) {
		System.out.println("带参数带返回值的方法!");
		return n + "哈哈大笑";
	}

	public void print() {
		System.out.println("不带参数不带返回值的方法!");
	}
}
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;

/**
 * @Description:编写自己的类加载器
 * @ClassName: FileSystemClassLoader
 * @Project: base-info
 * @Author: zxf
 * @Date: 2011-6-22
 */
public class FileSystemClassLoader extends ClassLoader {
	private String rootDir;

	public FileSystemClassLoader(String rootDir) {
		this.rootDir = rootDir;
	}

	protected Class<?> findClass(String name) throws ClassNotFoundException {
		byte[] classData = getClassData(name);
		if (classData == null) {
			throw new ClassNotFoundException();
		} else {
			return defineClass(name, classData, 0, classData.length);
		}
	}

	private byte[] getClassData(String className) {
		String path = classNameToPath(className);
		try {
			InputStream ins = new FileInputStream(path);
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			int bufferSize = 4096;
			byte[] buffer = new byte[bufferSize];
			int bytesNumRead = 0;
			while ((bytesNumRead = ins.read(buffer)) != -1) {
				baos.write(buffer, 0, bytesNumRead);
			}
			return baos.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	private String classNameToPath(String className) {
		return rootDir + File.separatorChar
				+ className.replace('.', File.separatorChar) + ".class";
	}

	public static void main(String args[]) {
		// A.class存放的目录包括com.yt.manager.classloader
		String classDataRootPath = "E:\\WorkSpaces";
		FileSystemClassLoader fscl1 = new FileSystemClassLoader(
				classDataRootPath);
		String className = "com.yt.manager.classloader.A";
		try {
			// 加载并初始化类
			Class<?> class1 = fscl1.loadClass(className);
			// 利用反射机制调用了print方法
			Method m = class1.getMethod("print");
			// class1.newInstance()实例化了A类,调用了A类对象的print方法。
			m.invoke(class1.newInstance());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

  ClassLoader类有如下三个主要方法:

  (1)、loadClass(String name,String resolve):该方法为ClassLoader的入口点,根据指定的二进制名称来加载类,系统就是调用ClassLoader的该方法来加载类的。

  (2)、findClass(String name):根据二进制名称来加载类。

注:如果需要实现自定义的ClassLoader,推荐使用findClass(String name)方法,因为该方法继承了父类委托和缓存机制的类加载机制。

   在ClassLoader中还有一个核心的方法:defineClass(String name,byte[] b,int off,int len),该方法负责将类的字节文件读入数组,并把它转化为Class对象,该字节码文件可以来源于网络、文件等。

 

参考文章:http://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html

分享到:
评论

相关推荐

    java类加载器

    ### Java 类加载器详解 #### 一、类加载器概述 在Java中,类加载器(Class Loader)是一项核心机制,用于将字节码(.class文件)加载到JVM中,使其成为运行时的对象。类加载器不仅实现了类的加载功能,还确保了...

    Java类加载器原理

    Java 类加载器原理 Java 类加载器是Java虚拟机(JVM)的核心组成部分,它负责将类的字节码加载到内存中并转换为可执行的Java类。类加载器的作用不仅仅是加载类,还包括确保类的唯一性,避免重复加载,并且遵循特定...

    java 类加载器 加密

    Java 类加载器是Java运行时环境的一个重要组成部分,它的主要职责是将编译后的字节码(.class文件)加载到JVM中,使得程序能够运行。类加载器的机制保证了类的唯一性,同时也提供了灵活性,允许我们自定义加载逻辑。...

    Java类加载器.pdf

    ### Java类加载器详解 Java类加载器是Java运行时环境的一个关键组成部分,负责将类文件(.class)从各种来源加载到JVM中。它不仅管理类的生命周期,还确保了类的正确加载和初始化,是Java动态特性的基石。 #### 类...

    自定义Java类加载器

    Java类加载器是Java虚拟机(JVM)的关键组成部分,它负责查找并加载类到内存中,使得程序能够运行。自定义Java类加载器允许我们根据特定需求扩展默认的加载机制,例如,从非标准位置加载类或者实现动态加载。在Java...

    java类加载器-tomcat中的类加载器

    Java 类加载器是Java虚拟机(JVM)的核心组成部分,它负责将编译后的字节码文件(.class文件)加载到JVM中并转换为运行时的数据结构。Tomcat,作为广泛使用的Java Servlet容器,它自定义了一套类加载机制,以满足Web...

    深入解析Java类加载器及其工作机制

    Java 类加载器是 Java 运行时环境中不可或缺的组成部分,负责将 .class 文件加载到 JVM 中。理解类加载器的工作原理对于深入掌握 Java 语言及其运行机制至关重要。本文将详细探讨 Java 类加载器的概念、类型以及工作...

    深入探讨 Java 类加载器

    【深入探讨 Java 类加载器】 Java 类加载器是Java虚拟机(JVM)的核心组成部分,它的主要任务是将Java类的字节码加载到JVM中以便执行。类加载器的概念始于JDK 1.0,最初是为了解决Java Applet在浏览器中的运行需求...

    关于Java类加载器的探讨.pdf

    扩展类加载器是Java实现的,是一个真正的Java类加载器,负责加载ire/lib/ext目录下的类,并且可以通过Java程序获得这个类加载器。 3. 系统类加载器:负责加载classpath中的类,也就是执行Java MainClass时加载Main...

    java类加载器实例

    类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一。它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java ...

    java 类加载器 class loader

    Java 类加载器(ClassLoader)是Java虚拟机(JVM)的核心组成部分,负责在运行时查找并加载类的字节码。了解ClassLoader的工作机制对于优化应用性能、实现安全控制以及进行插件化开发至关重要。 首先,Java的...

    Java类加载器的详解

    Java类加载器是Java虚拟机(JVM)的重要组成部分,它的主要职责是将类的字节码文件(.class文件)从文件系统、网络或内存中读取,并转换为运行时的java.lang.Class对象。这个过程是Java动态加载机制的核心,使得Java...

    java类加载器1

    Java 类加载器是Java语言的核心特性之一,它允许程序在运行时动态地加载类到Java虚拟机(JVM)中。这一特性对于实现模块化、插件化和动态部署等功能至关重要。类加载器的设计遵循“分层加载”原则,形成了一个树状的...

    java类加载器学习三、类加载器的委托模式

    java类加载器学习三、类加载器的委托模式

    Java类加载器机制与模型.pdf

    Java类加载器采用了**双亲委派模型(Parent Delegation Model)**,这意味着当一个类加载器收到加载类的请求时,它首先会委托其父类加载器去尝试加载,只有当父类加载器无法加载时,当前类加载器才会尝试自己加载。...

    Java类加载器(ClassLoader)1

    Java类加载器分为三种主要类型:引导类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用程序类加载器(Application ClassLoader,也称为系统类加载器)。它们共同工作,确保了Java...

    Java类加载器学习总结.pdf

    Java类加载器是Java运行时环境(JRE)的一个重要组成部分,它负责将Java字节码加载到内存中,使其可以被Java虚拟机(JVM)执行。类加载器本身也是一个类,它的主要职责是从文件系统、网络或者JAR包中加载类文件到JVM...

    深入探讨 Java 类加载器.wps

    深入探讨 Java 类加载器.wps深入探讨 Java 类加载器.wps深入探讨 Java 类加载器.wps

    深入探讨 Java 类加载器.pdf

    ### 深入探讨Java类加载器 #### 类加载器基本概念 类加载器(Class Loader)是Java语言的关键组成部分之一,它负责将Java类的字节码加载到Java虚拟机(JVM)中,从而使得Java应用程序能够运行起来。自Java诞生以来...

Global site tag (gtag.js) - Google Analytics