`

Java之ClassLoader

阅读更多

 

转载一文,自我学习!

 

Java之ClassLoader(一)基础概念 

shenkai 转贴  更新:2006-02-06 16:53:03  版本: 1.0  

 

静态库、动态连接库 

 

程序编制一般需经编辑、编译、连接、加载和运行几个步骤。在我们的应用中,有一些公共代码是需要反复使用,就把这些代码编译为“库”文件;在连接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中。这种库称为静态库,其特点是可执行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。 

 

为了克服这个缺点可以采用动态连接库。这个时候连接器仅仅是在可执行文件中打上标志,说明需要使用哪些动态连接库;当运行程序时,加载器根据这些标志把所需的动态连接库加载到内存。 

 

另外在当前的编程环境中,一般都提供方法让程序在运行的时候把某个特定的动态连接库加载并运行,也可以将其卸载(例如Win32的 LoadLibrary()&FreeLibrary()和Posix的dlopen()&dlclose())。这个功能被广泛地用于在程序运行时刻更新某些功能模块或者是程序外观。 

 

What is ClassLoader? 

 

与普通程序不同的是,Java程序(class文件)并不是本地的可执行程序。当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM里头运行,负责加载Java class的这部分就叫做Class Loader。 

 

JVM 本身包含了一个ClassLoader称为Bootstrap ClassLoader,和JVM一样,Bootstrap ClassLoader是用本地代码实现的,它负责加载核心Java Class(即所有java.*开头的类)。另外JVM还会提供两个ClassLoader,它们都是用 Java语言编写的,由Bootstrap ClassLoader加载;其中Extension ClassLoader负责加载扩展的 Java class(例如所有javax.*开头的类和存放在JRE的ext目录下的类),Application ClassLoader负责加载应用程序自身的类。 

 

When to load the class? 

 

什么时候JVM会使用ClassLoader加载一个类呢?当你使用java去执行一个类,JVM使用Application ClassLoader加载这个类;然后如果类A引用了类B,不管是直接引用还是用Class.forName()引用,JVM就会找到加载类A的ClassLoader,并用这个ClassLoader来加载类B。 

 

Why use your own ClassLoader? 

 

似乎JVM自身的ClassLoader已经足够了,为什么我们还需要创建自己的ClassLoader呢? 

 

因为JVM自带的ClassLoader只是懂得从本地文件系统加载标准的java class文件,如果编写你自己的ClassLoader,你可以做到: 

1)在执行非置信代码之前,自动验证数字签名 

2)动态地创建符合用户特定需要的定制化构建类 

3)从特定的场所取得java class,例如数据库中 

4) 等等 

 

事实上当使用Applet的时候,就用到了特定的ClassLoader,因为这时需要从网络上加载java class,并且要检查相关的安全信息。 

 

目前的应用服务器大都使用了ClassLoader技术,即使你不需要创建自己的ClassLoader,了解其原理也有助于更好地部署自己的应用。 

 

ClassLoader Tree & Delegation Model 

 

当你决定创建你自己的ClassLoader时,需要继承java.lang.ClassLoader或者它的子类。在实例化每个ClassLoader对象时,需要指定一个父对象;如果没有指定的话,系统自动指定ClassLoader.getSystemClassLoader()为父对象。如下图: 

 

 

在Java 1.2后,java class的加载采用所谓的委托模式(Delegation Modle),当调用一个ClassLoader.loadClass()加载一个类的时候,将遵循以下的步骤: 

1)检查这个类是否已经被加载进来了? 

2)如果还没有加载,调用父对象加载该类 

3)如果父对象无法加载,调用本对象的findClass()取得这个类。 

 

所以当创建自己的Class Loader时,只需要重载findClass()这个方法。 

 

Unloading? Reloading? 

 

当一个java class被加载到JVM之后,它有没有可能被卸载呢?我们知道Win32有FreeLibrary()函数,Posix有 dlclose()函数可以被调用来卸载指定的动态连接库,但是Java并没有提供一个UnloadClass()的方法来卸载指定的类。 

 

在Java中,java class的卸载仅仅是一种对系统的优化,有助于减少应用对内存的占用。既然是一种优化方法,那么就完全是JVM自行决定如何实现,对Java开发人员来说是完全透明的。 

 

在什么时候一个java class/interface会被卸载呢?Sun公司的原话是这么说的:"class or interface may be unloaded if and only if its class loader is unreachable. Classes loaded by the bootstrap loader may not be unloaded." 

 

事实上我们关心的不是如何卸载类的,我们关心的是如何更新已经被加载了的类从而更新应用的功能。JSP则是一个非常典型的例子,如果一个JSP文件被更改了,应用服务器则需要把更改后的JSP重新编译,然后加载新生成的类来响应后继的请求。 

 

其实一个已经加载的类是无法被更新的,如果你试图用同一个ClassLoader再次加载同一个类,就会得到异常(java.lang.LinkageError: duplicate class definition),我们只能够重新创建一个新的 ClassLoader实例来再次加载新类。至于原来已经加载的类,开发人员不必去管它,因为它可能还有实例正在被使用,只要相关的实例都被内存回收了,那么JVM就会在适当的时候把不会再使用的类卸载。

 

huangxiang回复于28日18点00分 

没有。 

在JVM中,如果一个已经被加载了的类,当它的所有对象都被GC后,这个类就有可能也被GC掉。 

但Java没有显示提供卸载已被加载到JVM中的类的方法。 

 

其次,JVM是通过 加载该类的加载器对象与该类的全限定名的组合 来唯一标识一个类的。 

所以,如果程序中要求使用相同全限定名的类时, 

可以通过重新创建一个加载器对象的方式来加载新的类, 

这样,先后两个类,其getClassLoader方法返回的是不同的对象。 

 

注意,上述说的类加载器,需要自己编写。因为java自带的ClassLoader抽象类中,默认的loadClass方法是交由父加载器类来完成的。 

编写自己的加载器时,要注意,defineClass方式是将类文件的字节码读入到JVM中, 

自定义的类加载器不调用(或不间接调用)该方法,是无法达到目的。

分享到:
评论

相关推荐

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

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

    java中classLoader的使用

    Java中的类加载器(ClassLoader)是Java虚拟机(JVM)的一个重要组成部分,它负责将类的.class文件从文件系统或者网络中加载到内存中,并转换为对应的Class对象。类加载器的工作流程主要包括加载、验证、准备、解析...

    Java ClassLoader定制实例

    在Java编程语言中,ClassLoader是一个至关重要的组成部分,它负责加载类到JVM(Java虚拟机)中。理解ClassLoader的工作原理以及如何定制它,对于深入学习Java的运行机制和进行高级应用开发具有重要意义。本篇文章将...

    java classloader classpath 张孝祥

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

    java classloader

    Java ClassLoader是一个核心的Java运行时组件,负责加载类到Java虚拟机(JVM)中。它是Java平台的独特特性,因为它允许动态加载类,增强了软件的可扩展性和灵活性。这篇博文(虽然链接不可用)可能深入探讨了...

    探究java的ClassLoader及类变量初始化顺序

    在Java编程语言中,ClassLoader是核心组件之一,它负责加载类到JVM(Java虚拟机)中。理解ClassLoader的工作机制以及类变量初始化的顺序对于深入理解Java运行时环境至关重要。这篇博文将探讨这两个主题。 首先,让...

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

    本Demo程序主要探讨的是Java中的ClassLoader等级关系,这一主题对于理解Java应用程序的运行机制至关重要。 首先,我们要了解ClassLoader的基本概念。在Java中,ClassLoader是一个系统组件,它根据指定的全限定类名...

    Java_ClassLoader详解

    在 Java 语言中,类加载器(ClassLoader)是 Java 运行时环境的核心组成部分之一,它负责将编译后的 `.class` 文件加载到 JVM 中执行。从 JDK 1.0 开始,随着 Java Applet 的出现以及网络应用的需求增加,类加载机制...

    理解Java ClassLoader机制

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

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

    Java ClassLoader机制是Java虚拟机(JVM)中一个至关重要的组成部分,它的主要任务是将类的.class文件加载到JVM中,使得程序能够运行。ClassLoader不仅负责类的加载,还涉及类的验证、初始化等一系列过程。理解...

    Java实现热加载完整代码;Java动态加载class;Java覆盖已加载的class;Java自定义classloader

    让Java支持热加载是个不错的想法。如何做到的呢? 1. 定义好接口和实现类 2. 让代理类通过反射的方式调用实现类,对外暴露的是代理类。 3. 自定义URLClassLoader。检查实现类.class文件的...Java自定义classloader;

    Java ClassLoader原理

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

    java中ClassLoader

    Java 中的 ClassLoader Java 中的 ClassLoader 是一个非常重要的组件,它负责动态加载 class 文件到虚拟机当中,并将其转换成 java.lang.Class 类的一个实例。每个这样的实例用来表示一个 Java 类,因此我们可以...

    java的ClassLoader类加载器机制

    Java的ClassLoader类加载器机制 在 Java 虚拟机(JVM)中,类加载器(ClassLoader)扮演着非常重要的角色。类加载器负责加载 Java 类,包括核心类和用户自定义类。在 JVM 运行过程中,类加载器会形成一个层次结构,...

    Java ClassLoader学习总结

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

    ClassLoader

    ### Java虚拟机中ClassLoader概述与双亲委托机制详解 #### 一、ClassLoader概念与作用 在Java编程语言中,`ClassLoader`是一个非常重要的组件,它负责加载程序运行所需的类文件到Java虚拟机(JVM)中。`ClassLoader`...

    Understanding the Java ClassLoader

    这种格式在多个方面与传统可执行程序格式不同,其中最显著的特点之一是Java程序并非单一的可执行文件,而是由许多单独的类文件组成,每个类文件对应一个Java类。 为了更好地理解和利用Java的这一特性,本篇将详细...

Global site tag (gtag.js) - Google Analytics