我的编程空间,编程开发者的网络收藏夹
学习永远不晚

JAVA的classloader怎么编写

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

JAVA的classloader怎么编写

今天小编给大家分享一下JAVA的classloader怎么编写的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

什么是 ClassLoader?

在流行的商业化编程语言中,Java 语言由于在 Java 虚拟机 (JVM) 上运行而显得与众不同。这意味着已编译的程序是一种特殊的、独立于平台的格式,并非依赖于它们所运行的机器。在很大程度上,这种格式不同于传统的可执行程序格式。

与 C 或 C++ 编写的程序不同,Java 程序并不是一个可执行文件,而是由许多独立的类文件组成,每一个文件对应于一个 Java 类。
此外,这些类文件并非立即全部都装入内存,而是根据程序需要装入内存。ClassLoader 是 JVM 中将类装入内存的那部分。
而且,Java ClassLoader 就是用 Java 语言编写的。这意味着创建您自己的 ClassLoader 非常容易,不必了解 JVM 的微小细节。

为什么编写 ClassLoader?

如果 JVM 已经有一个 ClassLoader,那么为什么还要编写另一个呢?问得好。缺省的 ClassLoader 只知道如何从本地文件系统装入类文件。不过这只适合于常规情况,即已全部编译完 Java 程序,并且计算机处于等待状态。

但 Java 语言最具新意的事就是 JVM 可以非常容易地从那些非本地硬盘或从网络上获取类。例如,浏览者可以使用定制的 ClassLoader 从 web 站点装入可执行内容。

有许多其它方式可以获取类文件。除了简单地从本地或网络装入文件以外,可以使用定制的 ClassLoader 完成以下任务:
在执行非置信代码之前,自动验证数字签名
使用用户提供的密码透明地解密代码
动态地创建符合用户特定需要的定制化构建类
任何您认为可以生成 Java 字节码的内容都可以集成到应用程序中。

定制 ClassLoader 示例

如果使用过 jdk 或任何基于 Java 浏览器中的 Applet 查看器,那么您差不多肯定使用过定制的 ClassLoader。

Sun 最初发布 Java 语言时,其中最令人兴奋的一件事是观看这项新技术是如何执行在运行时从远程的 Web 服务器装入的代码。(此外,还有更令人兴奋的事 -- Java 技术提供了一种便于编写代码的强大语言。)更一些令人激动的是它可以执行从远程 Web 服务器通过 HTTP 连接发送过来的字节码。

此项功能归功于 Java 语言可以安装定制 ClassLoader。Applet 查看器包含一个 ClassLoader,它不在本地文件系统中寻找类,而是访问远程服务器上的 Web 站点,经过 HTTP 装入原始的字节码文件,并把它们转换成 JVM 内的类。

浏览器和 Applet 查看器中的 ClassLoaders 还可以做其它事情:它们支持安全性以及使不同的 Applet 在不同的页面上运行而互不干扰。

Luke Gorrie 编写的 Echidna 是一个开放源码包,它可以使您在单个虚拟机上运行多个 Java 应用程序。它使用定制的 ClassLoader,通过向每个应用程序提供该类文件的自身副本,以防止应用程序互相干扰。

我们的 ClassLoader 示例

了解了 ClassLoader 如何工作以及如何编写 ClassLoader 之后,我们将创建称作 CompilingClassLoader (CCL) 的 Classloader。CCL 为我们编译 Java 代码,而无需要我们干涉这个过程。它基本上就类似于直接构建到运行时系统中的 "make" 程序。
注:进一步了解之前,应注意在 JDK 版本 1.2 中已改进了 ClassLoader 系统的某些方面(即 Java 2 平台)。本教程是按 JDK 版本 1.0 和 1.1 写的,但也可以在以后的版本中运行。

Java 2 中 ClassLoader 的变动描述了 Java 版本 1.2 中的变动,并提供了一些详细信息,以便修改 ClassLoader 来利用这些变动。

ClassLoader 的基本目标是对类的请求提供服务。当 JVM 需要使用类时,它根据名称向 ClassLoader 请求这个类,然后 ClassLoader 试图返回一个表示这个类的 Class 对象。 通过覆盖对应于这个过程不同阶段的方法,可以创建定制的 ClassLoader。

在本文的其余部分,您会学习 Java ClassLoader 的关键方法。您将了解每一个方法的作用以及它是如何适合装入类文件这个过程的。您也会知道,创建自己的 ClassLoader 时,需要编写什么代码。

在下文中,您将会利用这些知识来使用我们的 ClassLoader 示例 -- CompilingClassLoader。

方法 loadClass


ClassLoader.loadClass() 是 ClassLoader 的入口点。其特征如下:
Class loadClass( String name, boolean resolve );
name 参数指定了 JVM 需要的类的名称,该名称以包表示法表示,如 Foo 或 java.lang.object。 resolve 参数告诉方法是否需要解析类。在准备执行类之前,应考虑类解析。并不总是需要解析。如果 JVM 只需要知道该类是否存在或找出该类的超类,那么就不需要解析。

在 Java 版本 1.1 和以前的版本中,loadClass 方法是创建定制的 ClassLoader 时唯一需要覆盖的方法。(Java 2 中 ClassLoader 的变动提供了关于 Java 1.2 中 findClass() 方法的信息。)

方法 defineClass

defineClass 方法是 ClassLoader 的主要诀窍。该方法接受由原始字节组成的数组并把它转换成 Class 对象。原始数组包含如从文件系统或网络装入的数据。

defineClass 管理 JVM 的许多复杂、神秘和倚赖于实现的方面 -- 它把字节码分析成运行时数据结构、校验有效性等等。不必担心,您无需亲自编写它。事实上,即使您想要这么做也不能覆盖它,因为它已被标记成最终的。

方法 findSystemClass

findSystemClass 方法从本地文件系统装入文件。它在本地文件系统中寻找类文件,如果存在,就使用 defineClass 将原始字节转换成 Class 对象,以将该文件转换成类。当运行 Java 应用程序时,这是 JVM 正常装入类的缺省机制。(Java 2 中 ClassLoader 的变动提供了关于 Java 版本 1.2 这个过程变动的详细信息。)

对于定制的 ClassLoader,只有在尝试其它方法装入类之后,再使用 findSystemClass。原因很简单:ClassLoader 是负责执行装入类的特殊步骤,不是负责所有类。例如,即使 ClassLoader 从远程的 Web 站点装入了某些类,仍然需要在本地机器上装入大量的基本 Java 库。而这些类不是我们所关心的,所以要 JVM 以缺省方式装入它们:从本地文件系统。这就是 findSystemClass 的用途。

其工作流程如下:
请求定制的 ClassLoader 装入类。
检查远程 Web 站点,查看是否有所需要的类。
如果有,那么好;抓取这个类,完成任务。
如果没有,假定这个类是在基本 Java 库中,那么调用 findSystemClass,使它从文件系统装入该类。

在大多数定制 ClassLoaders 中,首先调用 findSystemClass 以节省在本地就可以装入的许多 Java 库类而要在远程 Web 站点上查找所花的时间。然而,正如,在下一章节所看到的,直到确信能自动编译我们的应用程序代码时,才让 JVM 从本地文件系统装入类。

方法 resolveClass

正如前面所提到的,可以不完全地(不带解析)装入类,也可以完全地(带解析)装入类。当编写我们自己的 loadClass 时,可以调用 resolveClass,这取决于 loadClass 的 resolve 参数的值。

方法 findLoadedClass

findLoadedClass 充当一个缓存:当请求 loadClass 装入类时,它调用该方法来查看 ClassLoader 是否已装入这个类,这样可以避免重新装入已存在类所造成的麻烦。应首先调用该方法。

组装

让我们看一下如何组装所有方法。
我们的 loadClass 实现示例执行以下步骤。(这里,我们没有指定生成类文件是采用了哪种技术 -- 它可以是从.NET 上装入、或者从归档文件中提取、或者实时编译。无论是哪一种,那是种特殊的神奇方式,使我们获得了原始类文件字节。)

CCL 揭密

我们的 ClassLoader (CCL) 的任务是确保代码被编译和更新。
下面描述了它的工作方式:
当请求一个类时,先查看它是否在磁盘的当前目录或相应的子目录。
如果该类不存在,但源码中有,那么调用 Java 编译器来生成类文件。
如果该类已存在,检查它是否比源码旧。如果是,调用 Java 编译器来重新生成类文件。
如果编译失败,或者由于其它原因不能从现有的源码中生成类文件,返回 ClassNotFoundException。
如果仍然没有该类,也许它在其它库中,所以调用 findSystemClass 来寻找该类。
如果还是没有,则返回 ClassNotFoundException。
否则,返回该类。
调用 findLoadedClass 来查看是否存在已装入的类。
如果没有,那么采用那种特殊的神奇方式来获取原始字节。
如果已有原始字节,调用 defineClass 将它们转换成 Class 对象。
如果没有原始字节,然后调用 findSystemClass 查看是否从本地文件系统获取类。
如果 resolve 参数是 true,那么调用 resolveClass 解析 Class 对象。
如果还没有类,返回 ClassNotFoundException。
否则,将类返回给调用程序。

Java 编译的工作方式

在深入讨论之前,应该先退一步,讨论 Java 编译。通常,Java 编译器不只是编译您要求它编译的类。它还会编译其它类,如果这些类是您要求编译的类所需要的类。
CCL 逐个编译应用程序中的需要编译的每一个类。但一般来说,在编译器编译完第一个类后,CCL 会查找所有需要编译的类,然后编译它。为什么?Java 编译器类似于我们正在使用的规则:如果类不存在,或者与它的源码相比,它比较旧,那么它需要编译。其实,Java 编译器在 CCL 之前的一个步骤,它会做大部分的工作。

当 CCL 编译它们时,会报告它正在编译哪个应用程序上的类。在大多数的情况下,CCL 会在程序中的主类上调用编译器,它会做完所有要做的 -- 编译器的单一调用已足够了。

然而,有一种情形,在第一步时不会编译某些类。如果使用 Class.forName 方法,通过名称来装入类,Java 编译器会不知道这个类时所需要的。在这种情况下,您会看到 CCL 再次运行 Java 编译器来编译这个类。在源代码中演示了这个过程。

使用 CompilationClassLoader

要使用 CCL,必须以特殊方式调用程序。不能直接运行该程序,如: % java Foo arg1 arg2
应以下列方式运行它:
% java CCLRun Foo arg1 arg2

CCLRun 是一个特殊的存根程序,它创建 CompilingClassLoader 并用它来装入程序的主类,以确保通过 CompilingClassLoader 来装入整个程序。CCLRun 使用 Java Reflection api 来调用特定类的主方法并把参数传递给它。有关详细信息,请参阅源代码。

运行示例

源码包括了一组小类,它们演示了工作方式。主程序是 Foo 类,它创建类 Bar 的实例。类 Bar 创建另一个类 Baz 的实例,它在 baz 包内,这是为了展示 CCL 是如何处理子包里的代码。Bar 也是通过名称装入的,其名称为 Boo,这用来展示它也能与 CCL 工作。

每个类都声明已被装入并运行。现在用源代码来试一下。编译 CCLRun 和 CompilingClassLoader。确保不要编译其它类(Foo、Bar、Baz 和 Boo),否则将不会使用 CCL,因为这些类已经编译过了。

% java CCLRun Foo arg1 arg2
CCL: Compiling Foo.java...
foo! arg1 arg2
bar! arg1 arg2
baz! arg1 arg2
CCL: Compiling Boo.java...
Boo!

请注意,首先调用编译器,Foo.java 管理 Bar 和 baz.Baz。直到 Bar 通过名称来装入 Boo 时,被调用它,这时 CCL 会再次调用编译器来编译它。

Foo.java
以下是 Foo.java 的源代码

// $Id$ public class Foo { static public void main( String args[] ) throws Exception { System.out.println( "foo! "+args[0]+" "+args[1] ); new Bar( args[0], args[1] ); } }

Bar.java
以下是 Bar.java 的源代码

// $Id$ import baz.*; public class Bar { public Bar( String a, String b ) { System.out.println( "bar! "+a+" "+b ); new Baz( a, b ); try { Class booClass = Class.forName( "Boo" ); Object boo = booClass.newInstance(); } catch( Exception e ) { e.printStackTrace(); } } }

baz/Baz.java
以下是 baz/Baz.java 的源代码

// $Id$ package baz; public class Baz { public Baz( String a, String b ) { System.out.println( "baz! "+a+" "+b ); } }

Boo.java
以下是 Boo.java 的源代码

// $Id$ public class Boo { public Boo() { System.out.println( "Boo!" ); } }

以上就是“JAVA的classloader怎么编写”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

JAVA的classloader怎么编写

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

JAVA的classloader怎么编写

今天小编给大家分享一下JAVA的classloader怎么编写的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。什么是 Clas
2023-06-03

JAVA classloader怎么理解

这篇文章给大家介绍JAVA classloader怎么理解,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。什么是 ClassLoader?在流行的商业化编程语言中,Java 语言由于在 Java 虚拟机 (JVM) 上运
2023-06-03

Java的ClassLoader是什么

本文小编为大家详细介绍“Java的ClassLoader是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java的ClassLoader是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。ClassLoad
2023-06-16

Java的ClassLoader有什么用

这篇文章主要介绍“Java的ClassLoader有什么用”,在日常操作中,相信很多人在Java的ClassLoader有什么用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java的ClassLoader有
2023-06-17

java中的classloader有什么功能

JavaClassLoader功能ClassLoader是Java虚拟机中负责加载、链接和初始化Java类的核心组件,其功能包括:类加载:加载.class文件,构建类型层次结构。类验证:确保加载的类符合规范,防止安全漏洞。依赖管理:按正确顺序加载和链接类。安全保护:控制对敏感资源的访问。可扩展性:允许创建自定义类加载器以满足特定需求。ClassLoader有四种主要类型:启动类加载器、扩展类加载器、系统类加载器和自定义类加载器,各有其加载位置和功能。通过调用loadClass()方法或创建自定义类加载器,
java中的classloader有什么功能
2024-04-11

Java的ClassLoader机制是什么

本篇内容介绍了“Java的ClassLoader机制是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!JVM在加载类的时候,都是通过Cla
2023-06-17

java怎么编写接口

在Java中,编写接口需要按照以下步骤进行:使用关键字`interface`来声明接口,接口的名称应该以大写字母开头,并且应该具有描述性的名称,以清楚地表示接口的用途。在接口中定义需要被实现的方法。方法的声明应该包含方法的返回类型、方法名
2023-10-26

java classloader的使用方法是什么

Java ClassLoader是Java虚拟机(JVM)的一个重要组成部分,用于加载Java类文件。ClassLoader负责将编译后的Java类文件加载到内存中,并在运行时实例化这些类。使用ClassLoader可以实现动态加载类、实现
java classloader的使用方法是什么
2024-04-09

java classloader的使用方法是什么

Java类加载器使用方法Java类加载器负责加载、链接和初始化类,确保应用程序加载正确的类并防止冲突。使用步骤:加载:从存储库读取类二进制表示。链接:连接类和解析符号引用。初始化:调用静态初始化程序。类型:引导类加载器:加载核心类库。扩展类加载器:加载扩展类路径中的类。系统类加载器:加载系统类路径中的类。自定义类加载器:由开发人员创建。使用:使用默认类加载器。创建自定义类加载器。设置类加载器。最佳实践:使用默认类加载器。仅在需要时创建自定义类加载器。考虑类加载委托的性能影响。测试自定义类加载器的行为。
java classloader的使用方法是什么
2024-04-12

java classloader的工作机制是什么

Java的ClassLoader是Java虚拟机(JVM)的一个重要组成部分,它主要负责加载Java类文件并把字节码文件转换成运行时的Class对象。ClassLoader的工作机制可以简单地描述为以下几个步骤:寻找类文件:ClassLo
java classloader的工作机制是什么
2024-04-09

java classloader的工作机制是什么

Java类加载器是一种分层系统,动态加载类定义。它包含三个主要类加载器:Bootstrap、扩展和系统,遵循分层和委托机制。每个加载器在自己的范围内加载类,并委托给父加载器加载不在其范围内的类。Java采用双亲委派模型,保证加载优先级和类隔离。开发人员还可以创建自定义类加载器以修改类加载行为。
java classloader的工作机制是什么
2024-04-10

怎么用Java编写ASP组件

这篇文章主要介绍怎么用Java编写ASP组件,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! ASP通过ActiveX Server Components(ActiveX 服务器元件 ) 使其具有无限可扩充性。在AS
2023-06-03

Java中怎么编写ASP组件

今天就跟大家聊聊有关Java中怎么编写ASP组件,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。先写个很简单的Java程序public class TestJava{public St
2023-06-03

java程序框架怎么编写

编写一个Java程序框架需要以下步骤:确定框架的目标和功能:明确框架的用途和提供的功能,例如Web开发框架、数据处理框架等。设计框架的架构:根据目标和功能,设计框架的整体架构,包括模块划分、类的设计等。实现框架的核心功能:根据架构设计,实现
2023-10-23

Java简单的SOAP客户端怎么编写

编写Java简单的SOAP客户端可以通过以下步骤进行:1. 导入必要的类和包。首先,需要导入`javax.xml.soap`包和相关的类。例如:```javaimport javax.xml.soap.*;```2. 创建SOAP连接。使用
2023-09-27

java怎么编写一个日期类

在Java中,可以通过以下步骤编写一个日期类:创建一个新的Java类,命名为Date。在Date类中定义私有变量来存储日期的年、月、日等信息,如:public class Date {private int year;private int
java怎么编写一个日期类
2024-03-14

怎么用JAVA写文本编辑器

本篇内容介绍了“怎么用JAVA写文本编辑器”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!为什么说这个简单,因为它需要完成的功能很少,只是出来
2023-06-25

java回文数程序怎么编写

以下是一个用Java编写的回文数程序示例:import java.util.Scanner;public class PalindromeNumber {public static void main(String[] args) {Sc
2023-10-23

怎么用java编写一个circular类

可以通过以下步骤来用Java编写一个Cirular类:1. 创建一个Circular类的Java文件,例如Circular.java。2. 在Circular类中声明私有的半径(radius)和圆心(center)变量,类型分别为doubl
2023-10-18

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录