`
zy19982004
  • 浏览: 661839 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
F6f66edc-1c1a-3859-b76b-a22e740b7aa7
Hadoop学习
浏览量:251950
社区版块
存档分类
最新评论

Java ClassLoader学习二:ClassLader源码

 
阅读更多

一.ClassLoader源码继承图

 

      SecureClassLoader:这个类我没做深入研究,你把它当成一个增强版的ClassLoader,增强了从何地load class,增强了能不能load这些代码权限。

 

二.源码

 

public abstract class ClassLoader {

	// 父ClassLoader
	private ClassLoader parent;

	// 被此classLoader加载过的Class对象
	private Vector classes = new Vector();
	
	// The packages defined in this class loader.  Each package name is mapped
    // to its corresponding Package object.
    private HashMap packages = new HashMap();

	// 由虚拟机调用
	void addClass(Class c) {
		classes.addElement(c);
	}

	// The packages defined in this class loader. Each package name is mapped
	// to its corresponding Package object.
	private final HashMap<String, Package> packages = new HashMap<String, Package>();

	// 指明parent
	protected ClassLoader(ClassLoader parent) {
		this(checkCreateClassLoader(), parent);
	}

	// 不指名parent时使用SystemClassLoader
	protected ClassLoader() {
		this(checkCreateClassLoader(), getSystemClassLoader());
	}

	// 默认resolve=false
	public Class<?> loadClass(String name) throws ClassNotFoundException {
		return loadClass(name, false);
	}

	protected synchronized Class<?> loadClass(String name, boolean resolve)
			throws ClassNotFoundException {
		// 1 检查此class是否被此classloader加载过,
		// 最终是有native方法返回,native方法会使用到classes集合
		Class c = findLoadedClass(name);
		// 1.1 未被加载
		if (c == null) {
			try {
				// 1.1.1 此classloader有parent,委托parent去load
				if (parent != null) {
					c = parent.loadClass(name, false);
				} else {// 1.1.2 此classloader无parent = 启动类装载器去加载
					c = findBootstrapClassOrNull(name);
				}
			} catch (ClassNotFoundException e) {
			}
			// 如果没有找到class,自己去加载试试
			if (c == null) {
				c = findClass(name);
			}
		}
		// 找到的Class对象是否需要连接操作
		if (resolve) {
			resolveClass(c);
		}
		// 1.2 被加载过,直接返回
		return c;
	}

	protected final Class<?> findLoadedClass(String name) {
		if (!checkName(name))
			return null;
		return findLoadedClass0(name);
	}

	// 如果name里包含/,或者虚拟机不支持class数组你使用了数组的时候返回false,其它情况返回true,包括空的name
	// eg com.jyz.component.core.collection.Tuple return true
	private boolean checkName(String name) {
		if ((name == null) || (name.length() == 0))
			return true;
		if ((name.indexOf('/') != -1)
				|| (!VM.allowArraySyntax() && (name.charAt(0) == '[')))
			return false;
		return true;
	}

	// 检查package是否可访问
	private void checkPackageAccess(Class cls, ProtectionDomain pd) {
		final SecurityManager sm = System.getSecurityManager();
		if (sm != null) {
			// ...
		}
		domains.add(pd);
	}

	// 自定义classloader时重写此方法
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		throw new ClassNotFoundException(name);
	}

	// 将byte数组转换成一个Class对象,最终有native方法实现
	// 同一个byte数组,被不同的classloader加载,产生两个不同的Class对象
	protected final Class<?> defineClass(String name, byte[] b, int off, int len)
			throws ClassFormatError {
		return defineClass(name, b, off, len, null);
	}

	/*
	 * Determine protection domain, and check that: - not define java.* class, -
	 * signer of this class matches signers for the rest of the classes in
	 * package.
	 */
	//native的defineClass时会调用此方法检查name是否合法
	//首先checkName,然后还需要!name.startsWith("java.")
	//所以我们定义了java.mypackage包,都将异常
	//java.lang.SecurityException: Prohibited package name: java.mypackage
	private ProtectionDomain preDefineClass(String name,
			ProtectionDomain protectionDomain) {
		if (!checkName(name))
			throw new NoClassDefFoundError("IllegalName: " + name);
		if ((name != null) && name.startsWith("java.")) {
			throw new SecurityException("Prohibited package name: "
					+ name.substring(0, name.lastIndexOf('.')));
		}
		//...
	}

	// protected的resolveClass方法,可以在自定义的classloader调用
	protected final void resolveClass(Class<?> c) {
		resolveClass0(c);
	}
	
	//获得appClassLoader,实际调用Launcher完成
	public static ClassLoader getSystemClassLoader() {
		sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
		return l.getClassLoader();
    }

}

 

 

三.源码说明 

  1.  loadClass这个类是重点。
      1. 检查此class是否被此classloader加载过,有直接返回此class
      2. 检查此ClassLoader有无parent,有委托parent去load。无说明此CassLoader为ExtClassLoader,交给BootstrapLoader去加载。其实可以说委托parent去加载
      3. 某个ClassLoaer的parent并未加载到指定class,自己findClass(String name)去加载。
      4. 最后判断找到的Class对象是否需要连接操作并执行。
  2. 自定义classloader时重写findClass(String name)。
  3. ClassLoader.etSystemClassLoader()实际由sun.misc.Launcher去完成。
  4. ClassLoader构造函数里,不指名parent的话使用AppClassLoader。

 

 

0
0
分享到:
评论

相关推荐

    Java ClassLoader学习总结

    Java ClassLoader学习总结 Java 类加载机制是 Java 中一个非常重要的机制,它负责加载 Class 文件到 JVM,以供程序使用。ClassLoader 是 Java 中的一个抽象类,它的主要作用是加载 Class 文件到 JVM 中。...

    Java ClassLoader原理

    ### Java ClassLoader原理详解 #### 摘要 本文探讨了Java虚拟机(JVM)中的一个重要特性:动态类加载(Dynamic Class Loading)。这一机制为Java平台提供了强大的能力,允许在运行时安装软件组件,例如从网络下载...

    Java ClassLoader定制实例

    理解ClassLoader的工作原理以及如何定制它,对于深入学习Java的运行机制和进行高级应用开发具有重要意义。本篇文章将深入探讨Java ClassLoader的内部工作,并通过一个具体的实例来展示如何定制自己的ClassLoader。 ...

    Understanding the Java ClassLoader

    通过本教程的学习,你将能够理解Java ClassLoader的基本概念及其工作原理,并学会如何创建自定义的ClassLoader。自定义ClassLoader不仅能够扩展JVM的功能,还能够在实际项目中解决特定问题,如动态加载远程资源、...

    java classloader

    `附录A.Java 2 SDK版原始码概观.pdf`可能提供了Java 2 SDK源码的概述,这对于理解ClassLoader的工作方式非常有帮助,因为你可以看到其内部的实现细节。 `CH_00-导读.pdf`则可能是整个系列的引导章节,介绍了接下来...

    resolver_java_wsdl.jar

    at java.lang.ClassLoader.loadClassHelper(ClassLoader.java:688) at java.lang.ClassLoader.loadClass(ClassLoader.java:667) at com.ibm.ws.bootstrap.ExtClassLoader.loadClass(ExtClassLoader.java:119) at...

    java classloader讲义-淘宝网

    ### Java ClassLoader详解:以淘宝网为例 #### 一、ClassLoader概述 在Java环境中,类加载器(ClassLoader)是负责加载Java类到JVM的重要组件。它不仅实现了类的加载机制,还支持了动态加载与卸载的功能。本文将...

    aop面向切面需要的jar包

    at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:252) at java.lang....

    java classloader classpath 张孝祥

    ### Java ClassLoader与ClassPath详解 #### 一、概述 在Java编程中,类加载机制是十分关键的一个环节。类加载器(`ClassLoader`)负责将编译后的`.class`文件加载到Java虚拟机(JVM)中执行,而类路径(`ClassPath...

    java ClassLoader机制及其在OSGi中的应用

    Java提供了三种内置的ClassLoader: 1. BootstrapClassLoader(启动类加载器):它是JVM的基础,由C++实现,不继承自`java.lang.ClassLoader`。BootstrapClassLoader负责加载JVM的核心类库,包括rt.jar、charsets....

    破解java加密的ClassLoader.java,在classloader植入破解代码

    破解java加密的ClassLoader.java,在classloader植入破解代码

    理解Java ClassLoader机制

    Java ClassLoader机制是Java运行时环境中的核心组件之一,它负责加载类到JVM(Java虚拟机)中,使得程序能够执行。理解ClassLoader的工作原理对于优化应用性能、处理类加载问题以及实现自定义加载器至关重要。 首先...

    测试普通Java程序ClassLoader等级关系的Demo程序

    Java虚拟机(JVM)是Java程序运行的基础,它通过加载、验证、解析和执行字节码来实现程序的运行。在JVM中,类加载器(ClassLoader)扮演着至关重要的...通过实践和学习,我们能够提升Java编程的技能和解决问题的能力。

    classloader源码

    深入理解`ClassLoader`的源码对于Java开发者来说是提升技能的重要环节,尤其是在进行模块化、插件化开发或者进行系统优化时。自定义`ClassLoader`能够帮助我们实现特定的加载策略,比如隔离不同版本的库或动态加载类...

    Java ClassLoader Tutorial.zip

    1. 继承ClassLoader:开发者可以通过继承`java.lang.ClassLoader`并重写`loadClass()`方法来自定义类加载逻辑。 2. 加载自定义位置的类:自定义ClassLoader可以加载非标准路径的类,如从网络、数据库或其他存储介质...

    Java SE: ClassLoader in depth

    在Java中,有几种不同类型的ClassLoader: - 启动类加载器(Bootstrap ClassLoader):负责加载JAVA_HOME/lib目录下的,或被-Xbootclasspath参数指定路径中的,并且是虚拟机识别的类库到JVM中。 - 扩展类加载器...

    xwiki-commons-classloader-protocol-jar-5.4.zip

    《XWiki Commons Classloader Protocol Jar 5.4与LaZyWorker开源项目...这两个项目都体现了开源社区的创新精神和对软件性能优化的执着追求,对于学习和实践Java编程、类加载机制以及优化策略的开发者具有极高的价值。

Global site tag (gtag.js) - Google Analytics