实现JAVA的动态类载入机制

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>

作 为 充 分 利 用Java 的 动 态 类 载 入 机 制 的 最 好 例 子, 带 有Java 扩 展 的Web 浏 览 器 根 据 请 求 从 网 络 或 本 地 文 件 系 统 中 动 态 加 载Java applet( 遵 循 一 定 规 则 的Java 小 应 用 程 序 类), 然 后 在 本 地 系 统 中 执 行 它, 大 大 增 强 了 主 页 的 功 能。

---- 其 实,Java 本 身 就 是 一 种 极 具 动 态 性 的 语 言。 类 似Windows 的 动 态 链 接 库(DLL),Java 应 用 程 序 总 是 被 编 译 成 若 干 个 单 独 的class 文 件, 程 序 执 行 时 根 据 需 要 由Java 虚 拟 机 动 态 载 入 相 应 的 类。 这 种 机 制 使 编 写 动 态 的 分 布 式 应 用 程 序 成 为 可 能: 我 们 可 以 在 客 户 端 编 写 自 己 的 类 载 入 器, 而 真 正 执 行 的 程 序 却 存 放 在 本 地、 局 域 网 或 世 界 另 一 端 的 主 机 上。 下 面 将 介 绍 如 何 在 自 己 的 应 用 程 序 中 实 现Java 的 动 态 类 载 入 机 制。

与 动 态 类 载 入 有 关 的 系 统 类

---- 为 支 持 动 态 类 载 入 机 制, 在 系 统 类 组java.lang 中 提 供 了 两 个 类:Class 类 和ClassLoader 类。

---- 1、 类java.lang.Class。 在Java 虚 拟 机 中, 每 一 个 类 或 接 口 都 是 由Class 类 来 操 纵 的, 它 不 能 被 显 式 的 实 例 化, 必 须 用 其 他 方 法 来 获 取Class 类 的 对 象。 动 态 类 载 入 机 制 的 关 键 一 步 在 于 如 何 获 得 指 定 类 的Class 类 型 的 对 象。 相 关 方 法 主 要 有:

---- public static Class forName(String className)

---- 这 是 一 个 静 态 方 法, 它 获 取 指 定 名 字 的 类 的Class 类 型 对 象, 类 名 可 以 是 象“sun.applet.Applet” 这 样 的 字 符 串, 但 不 能 带 有 路 径 或 网 络 地 址 等 信 息。 这 是 从 本 地 系 统 中 动 态 载 入 类 的 最 方 便 的 办 法。

---- public Object newInstance()

---- 这 是 最 重 要 的 一 个 方 法, 它 建 立 由Class 类 型 对 象 描 述 的 指 定 类 的 实 例。

---- 下 面 是 一 个 用forName() 和newInstance() 方 法 实 现 动 态 类 载 入 的 代 码,share 类 包 含 一 个 接 口, 详 细 内 容 将 在 第 三 部 分 中 解 释。


try{

//根据类名建立Class类型的对象。

Class cc =Class.forName("类名"));

//建立被载入类类的实例并强制类型转换,

 值赋给share类型的变量。

share oo=((share)cc).newInstance();

//调用该类的方法进行工作。

}

catch (Exception ex){

//如果发生例外,则进行相应处理。

};

---- 2、 类java.lang.ClassLoader。 这 是 一 个 抽 象 类, 如 果 打 算 运 用 它, 必 须 继 承 它 并 重 写 它 的loadClass() 方 法。 其 主 要 方 法 有:

---- protected ClassLoader();

---- 这 是 一 个 建 构 元, 可 以 用 它 建 立 一 个ClassLoader 类 的 实 例。 注 意 继 承 这 个 类 的 类 必 须 重 写 这 个 方 法, 而 不 能 使 用 缺 省 的 建 构 元。

---- protected abstract Class loadClass(String name, boolean resolve)

---- 载 入 指 定 的 类 数 据, 建 立Class 类 型 的 对 象 并 根 据 需 要 解 析 它。 这 是 一 个 抽 象 方 法, 大 家 必 须 在 自 己 的 子 类 中 重 写 这 个 方 法, 重 写 的 规 则 可 以 参 考 第 三 部 分 的 例 子。

---- protected final Class defineClass(byte data[], int offset, int length)

---- 将 字 节 数 组 中 的 数 据 定 义 为Class 类 型 的 对 象, 字 节 数 组 的 格 式 由 虚 拟 机 规 定。

---- protected final Class findSystemClass(String name)

---- 根 据 指 定 的 类 名 载 入 类, 它 会 自 动 在 当 前 目 录 和 环 境 变 量“CLASSPATH” 指 定 的 路 径 中 寻 找, 如 果 找 不 到, 则 会 抛 出ClassNotFoundException 例 外。

---- protected final void resolveClass(Class c)

---- 通 过 载 入 与 指 定 的 类 相 关 的 所 有 类 来 解 析 这 个 类, 这 必 须 在 类 被 使 用 之 前 完 成。

扩 充ClasslLader 类 以 实 现 动 态 类 载 入

---- 理 解 动 态 类 载 入 机 制 的 最 好 办 法 是 通 过 例 子, 下 面 这 个 完 整 的 例 子 由 四 个 类 组 成, 分 别 解 释 如 下:

---- 1、MyClassLoader 类 是ClassLoader 类 的 子 类, 它 重 写 了loadClass 方 法, 实 现 了 将 网 络 上 用URL 地 址 指 定 的 类 动 态 载 入, 取 得 它 的Class 类 型 对 象 的 功 能。 读 者 可 根 据 自 己 载 入 类 的 具 体 方 式 改 写 下 面 的 代 码。


import java.io.*;

import java.util.*;

import java.net.*;



public class MyClassLoader extends ClassLoader {	

	//定义哈希表(Hashtable)类型的变量,

     用于保存被载入的类数据。

	Hashtable loadedClasses;



	public MyClassLoader() {

		loadedClasses = new Hashtable();

	}



public synchronized Class loadClass(String className,

		boolean resolve) throws ClassNotFoundException {

		Class newClass;

		byte[] classData;

		

		//检查要载入的类数据是否已经被保存在哈希表中。

		newClass = (Class) loadedClasses.get(className);

		//如果类数据已经存在且resolve值为true,则解析它。

		if (newClass != null){

			if (resolve) 

				resolveClass(newClass);

			return newClass;

		}

---- /* 首 先 试 图 从 本 地 系 统 类 组 中 载 入 指 定 类。 这 是 必 须 的, 因 为 虚 拟 机 将 这 个 类 载 入 后, 在 解 析 和 执 行 它 时 所 用 到 的 任 何 其 他 类, 如java.lang.System 类 等, 均 不 再 使 用 虚 拟 机 的 类 载 入 器, 而 是 调 用 我 们 自 制 的 类 载 入 器 来 加 载。*/


		try {

			newClass = findSystemClass(className);

			return newClass;

		} catch (ClassNotFoundException e) {

			System.out.println(className " is not a system class!");

		}



		//如果不是系统类,

         则试图从网络中指定的URL地址载入类。

		try {

			//用自定义方法载入类数据,

             存放于字节数组classData中。

			classData = getClassData(className);

			//由字节数组所包含的数据建立一个class类型的对象。

			newClass = defineClass(classData, 0, classData.length);

			if (newClass == null)

				throw new ClassNotFoundException(className);

		} catch (Exception e) {

			throw new ClassNotFoundException(className);

		}



		//如果类被正确载入,

         则将类数据保存在哈希表中,以备再次使用。

		loadedClasses.put(className, newClass);

		//如果resolve值为true,则解析类数据。

		if (resolve){

			resolveClass(newClass);

			}

		return newClass;

     }

	//这个方法从网络中载入类数据。

protected byte[] getClassData(String className)

throws IOException {

	byte[] data;

	int length;

		try {

			//从网络中采用URL类的方法

             载入指定URL地址的类的数据。

			URL url = new URL(className.endsWith(".class") ?

                     className : className   ".class");

			URLConnection connection = url.openConnection();

			InputStream inputStream = connection.getInputStream();

			length = connection.getContentLength();



			data = new byte[length];

			inputStream.read(data); 

			inputStream.close();

			return data;

		} catch(Exception e) {

			throw new IOException(className);

		}

	}

}

---- 2、 由 于Java 是 强 类 型 检 查 语 言, 通 过 网 络 载 入 后 的 类 被 实 例 化 后 只 是 一 个Object 类 型 的 对 象, 虚 拟 机 并 不 知 道 它 包 含 那 些 方 法, 应 从 哪 个 方 法 开 始 执 行。 因 此, 可 以 被 动 态 载 入 的 类 必 须 继 承 某 一 个 抽 象 类 或 实 现 某 一 个 接 口, 因 为 父 类 只 能 有 一 个, 所 以 通 常 用 实 现 特 定 接 口 的 办 法。 下 面 的 代 码 定 义 了 一 个 接 口 类share 和 它 的 方 法start()。


public interface share {

	public void start(String[] option);

}

---- 3、TestClassLoader 类 通 过 使 用MyClassLoader 类 的loadClass() 方 法, 将 指 定URL 地 址 的 类 载 入 并 在 本 地 系 统 执 行 它, 实 现 了 类 的 动 态 载 入。 注 意 在 执 行 被 载 入 类 的 方 法 前 一 定 要 将 它 进 行 强 制 数 据 类 型 转 换。


public class TestClassLoader {

	public static void main(String[] args){

		MyClassLoader ll = new MyClassLoader();

      Class cc;

		Object oo;

      String ss = "http://kyzser.ydxx/classLoader/Tested.class";



      if (args.length != 0) ss = args[0];

      try {

		System.out.println("Loading class " ss "...");

			//使用重写的方法loadClass()载入类数据。

				cc = ll.loadClass(ss);

				System.out.println("Creat instance...");

				//创建Object类型的类实例。

				oo = cc.newInstance();

				System.out.println("Call start() method..."); 

 				//强制类型转换并执行被载入类中的方法。

				((share) oo).start(args);

        	}catch (Exception e) {

        	System.out.println("Caught exception : " e);

    		}

}

}

---- 4、Tested 类 很 简 单, 可 以 将 它 放 在 任 何WEB 服 务 器 上, 但 应 注 意 能 动 态 载 入 且 被 执 行 的 类, 一 定 要 实 现 预 先 定 义 的 接 口 中 的 方 法。 下 面 的 例 子 实 现 了 接 口share 的start 方 法。


public class Tested implements share{

	public void start(String[] option){

		//填写程序代码。

	}

}

动 态 类 载 入 机 制 的 几 点 应 用

---- 1、 开 发 分 布 式 应 用。 这 对 开 发 远 程 的 客 户 端 应 用 程 序 最 有 用, 客 户 端 仅 需 要 安 装 一 些 基 本 的 系 统 和 一 个 能 实 现 动 态 类 载 入 机 制 的 类, 需 要 本 地 系 统 不 存 在 的 功 能 时, 仅 需 要 从 网 络 动 态 载 入 并 执 行 相 应 类 即 可 获 得 特 定 功 能。 因 为 客 户 端 所 使 用 的 总 是 软 件 的 最 新 版 本, 所 以 不 再 存 在 软 件 的 升 级 和 维 护 问 题, 即 实 现 了 所 谓 的“ 零 管 理” 模 式。

---- 2、 对.class 文 件 加 密。 由 于Java 的 字 节 码(bytecode) 容 易 被 反 编 译, 大 部 分 开 发Java 应 用 程 序 的 公 司 均 担 心 自 己 的 成 果 被 别 人 不 劳 而 获。 其 实 可 以 将 类 文 件 进 行 适 当 的 加 密 处 理, 执 行 时 使 用 自 己 的 类 载 入 器 进 行 相 应 的 解 密, 就 可 以 解 决 这 个 问 题。

---- 3、 使 第 三 方 开 发 者 易 于 扩 展 你 的 应 用。 从 前 面 可 知, 所 有 可 以 被 你 的 类 载 入 器 动 态 载 入 并 被 执 行 的 类, 必 须 继 承 你 定 义 的 类 或 实 现 你 定 义 的 接 口, 这 样, 你 可 以 制 订 一 些 规 则, 使 其 他 开 发 者 不 必 了 解 你 的 应 用 程 序 也 可 以 扩 充 功 能。

---- 当 然, 有 利 必 有 弊, 在 网 络 中 使 用 动 态 类 载 入 的 主 要 缺 陷 在 于 安 全 性, 很 难 保 证 不 载 入 不 怀 好 意 的 代 码, 这 个 问 题 要 靠Java 的 安 全 管 理 器 和 适 当 的 加 密 算 法 来 解 决, 已 超 出 本 文 的 讨 论 范 围。

Ionic 4 + Capacitor 定位实战:权限、真机适配与性能优化 地理位置(Geolocation)是混合应用的核心能力之一,其底层依赖 Web API 与原生平台的深度协同。在 Capacitor 架构中,定位并非简单调用 `navigator.geolocation`,而是涉及权限声明、JS Bridge 桥接、Android/iOS 原生服务调度及后台策略等多层机制。尤其在 Android 12+ 和 iOS 16+ 系统下,`permissions policy violation` 和 `location access blocked` 等错误频发,本质是运行时 阅读详情

相关推荐

java动态类加载_实现Java动态类载入机制

作 为 充 分 利 用Java 的 动 态 类 载 入 机 制 的 最 好 例 子, 带 有Java 扩 展 的Web 浏 览 器 根 据 请 求 从 网 络 或 本 地 文 件 系 统 中 动 态 加 载Java applet( 遵 循 一 定 规 则 的Java 小 应 用 程 序 类), 然 后 在 本 地 系 统 中 执 行 它, 大 大 增 强 了 主 页 的 功 能。---- 其 实,...

weixin_30937427的博客 747

Java技术----实现JAVA动态类载入机制

[code="java"] ----作为充分利用Java动态类载入机制的最好例子,带有Java扩展的Web浏览器根据请求从网络或本地文件系统中动态加载Javaapplet(遵循一定规则的Java小应用程序类),然后在本地系统中执行它,大大增强了主页的功能。 ----其实,Java本身就是一种极具动态性的语言。类似Windows的动态链接库(DLL),Java应用程序总是被编译成若干个单独...

yg_201314的专栏 115

实现Java动态类载入机制

作 为 充 分 利 用Java 的 动 态 类 载 入 机 制 的 最 好 例 子, 带 有Java 扩 展 的Web 浏 览 器 根 据 请 求 从 网 络 或 本 地 文 件 系 统 中 动 态 加 载Java applet( 遵 循 一 定 规 则 的Java 小 应 用 程 序 类), 然 后 在 本 地 系 统 中 执 行 它, 大 大 增 强 了 主 页 的 功 能。 ---- 其 实

自由引导码民! 867

利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换

   作者:54dabang 在spring的学习过程之中,我们能够看出通过配置文件来动态管理bean对象的优点(松耦合 能够让零散部分组成一个总体,而这些总体并不在意之间彼此的细节,从而达到了真正的物理上的疏散耦合,而非逻辑,有了IOC之后。我们能够让SPRING充当各框架中的整合器。把技术框架进行完美的结合)。 Spring实现的一个重要的机制是通过反射(java.lang.ref...

weixin_34349320的博客 801

实 现JAVA 的 动 态 类 载 入 机 制

作 为 充 分 利 用Java 的 动 态 类 载 入 机 制 的 最 好 例 子, 带 有Java 扩 展 的Web 浏 览 器 根 据 请 求 从 网 络 或 本 地 文 件 系 统 中 动 态 加 载Java applet( 遵 循 一 定 规 则 的Java 小 应 用 程 序 类), 然 后 在 本 地 系 统 中 执 行 它, 大 大 增 强 了 主 页 的 功 能。 ---- 其 实

曲径通幽,冥思致远 1097

java动态获取配置_利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换...

作者:54dabang在spring的学习过程之中,我们能够看出通过配置文件来动态管理bean对象的优点(松耦合 能够让零散部分组成一个总体,而这些总体并不在意之间彼此的细节,从而达到了真正的物理上的疏散耦合,而非逻辑,有了IOC之后。我们能够让SPRING充当各框架中的整合器。把技术框架进行完美的结合)。Spring实现的一个重要的机制是通过反射(java.lang.reflect)读取配置文件...

weixin_29196315的博客 464

实 现JAVA 的 动 态 类 载 入 机 制 选择自 magicwizard 的 Blog

作 为 充 分 利 用Java 的 动 态 类 载 入 机 制 的 最 好 例 子, 带 有Java 扩 展 的Web 浏 览 器 根 据 请 求 从 网 络 或 本 地 文 件 系 统 中 动 态 加 载Java applet( 遵 循 一 定 规 则 的Java 小 应 用 程 序 类), 然 后 在 本 地 系 统 中 执 行 它, 大 大 增 强 了 主 页 的 功 能。 ---- 其 实

ycp518的专栏 740

java加载机制(java加载机制使用什么模型)

Java加载类的机制是怎样的? sun。com/developer /TechTips/2000/tt1027。html Writing Your Own Class Loader The loadClass method of the ClassLoader superclass takes care of...

计算机毕业论文源码,学生个人网页制作html源码。贴近用户做网络推广和互联网优化。 255

打造自己的类载入

Java是一种极具动态性的语言。类似Windows的动态链接库,Java应用程序总是被编译成若干个单独的class文件, 程序执行时根据需要由java虚拟机动态载入相关的类。这种机制使编写动态的分布式应用程序成为可能:我们可以 在客户端编写自己的类载入器,而真正执行的程序却存放在本地、局域网或世界另一端的主机上。下面将介绍 如何在应用程序中实现java动态类载入机制。 与动态类载入有关的

程序人生的专栏 619

java 解析dex_Android动态载入Dex机制解析

1.什么是类载入器?类载入器(class loader)是 Java™中的一个非常重要的概念。类载入器负责载入 Java 类的字节代码到 Java 虚拟机中。Java 虚拟机使用 Java 类的方式例如以下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类载入器负责读取 Java 字节代码,并转换成java.lang.Cl...

weixin_33335851的博客 398

Java反射机制的应用场景

反射的优势和劣势 个人理解,反射机制实际上就是上帝模式,如果说方法的调用是 Java 正确的打开方式,那反射机制就是上帝偷偷开的后门,只要存在对应的class,一切都能够被调用。 那上帝为什么要打开这个后门呢?这涉及到了静态和动态的概念 静态编译:在编译时确定类型,绑定对象 动态编译:运行时确定类型,绑定对象 两者的区别在于,动态编译可以最大程度地支持多态,而多态最大的意义在于降低类的耦合性,因此反射的优点就很明显了:解耦以及提高代码的灵活性。 因此,反射的优势和劣势分别在于: 优势 运行期类型的判断,动态

qq_36789243的博客 377

java生成动态类的几种方法

java生成动态类

qszfly的博客 2051
上一篇: Java 的i18n问题
下一篇: 用Java绘制K线
java169
博客等级 码龄18年 27粉丝 2568原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值