分享
 
 
 

Java类加载原理及自定义类加载器

王朝学院·作者佚名  2009-12-03
窄屏简体版  字體: |||超大  

Java和其他语言不同的是,Java是运行于Java虚拟机(JVM)。这就意味着编译后的代码是以

一种和平台无关的格式保存的,而不是某种特定的机器上运行的格式。这种格式和传统的可

执行代码格式有很多重要的区别。具体来说,不同于C或者C++程序,Java程序不是一个独

立的可执行文件,而是由很多分开的类文件组成,每个类文件对应一个Java类。 另外,这

些类文件并不是马上加载到内存,而是当程序需要的时候才加载。 类加载器就是Java虚拟

机中用来把类加载到内存的工具。而且,Java类加载器也是用Java实现的。这样你就不需要

对Java虚拟机有深入的理解就可以很容易创建自己的类加载器了。

为什么要创建类加载器?

既然Java虚拟机已经有了类加载器,我们还要自己创建其他的吗?问得好。默认的类加载器

只知道如何从本地系统加载类。当你的程序完全在本机编译的话,默认的类加载器一般都工

作的很好。但是Java中最激动人心的地方之一就是很容易的从网络上而不只是本地加载类。

举个例子,浏览器可以通过自定义的类加载器加载类。 还有

很多加载类的方式。除了简单的从本地或者网络外,你还可以通过自定义Java中最激动人心

的地方之一:

* 执行非信任代码前自动验证数字签名

* 根据用户提供的密码解密代码

* 根据用户的需要动态的创建类

你关心的任何东西都能方便的以字节码的形式集成到你的应用中

自定义类加载器的例子

如果你已经使用过JDK(Java软件开发包)中的appletviewer(小应用程序浏览器)或者其他

Java嵌入式浏览器,你就已经使用了自定义类加载器了。Sun刚刚发布Java语言的时候,最

令人兴奋的一件事就是观看Java如何执行从远程网站下载的代码。执行从远程站点通过HTT

P连接传送来的字节码看起来有点不可思议。之所以能够工作,因为Java有安装自定义类加

载器的能力。小应用程序浏览器包含了一个类加载器,这个类加载器不从本地找Java类,而

是访问远程服务器,通过HTTP加载原始字节码文件,然后在Java虚拟机中转化为Java类。当

然类加载器还做了其他的很多事情:他们阻止不安全的Java类,而且保持不同页面上的不同

小程序不会互相干扰。Luke Gorrie写的一个包Echidna是一个开放的Java软件包,他允许在

一个Java虚拟机中安全的运行多个Java应用程序。它通过使用自定义类加载器给每个应用程

序一份类文件的拷贝来阻止应用程序之间的干扰。

java类加载器 :

java中默认有三种类加载器:引导类加载器,扩展类加载器,系统类加载器(也叫应用类加载器)

类加载器是Java最强大的特征之一。但是开发者常常忘记类加载组件。类加载器是在运行时负责寻找和加载类文件的类。Java允许使用不同的类加载器,甚至自定义的类加载器。

Java 程序包含很多类文件,每一个都与单个Java类相对应,这些类文件不像静态C程序,一次性加载入内存,它们随时需要随时加载。这就是类加载器与众不同的地 方。它从源文件(通常是.class 或 .jar文件)获得不依赖平台的字节码,然后将它们加载到JVM内存空间,所以它们能被解释和执行。默认状态下,应用程序的每个类由 java.lang.ClassLoader加载。因为它可以被继承,所以可以自由地加强其功能。

自定义类加载器

import java.io.*;

import java.net.*;

import java.util.*;

import java.lang.reflect.Method;

public class CustomClassLoader extends URLClassLoader {

private FileInputStream input = null; //文件输入流

private ByteArrayOutputStream out = null; //字节数组输出流

private String[] url = null; //类文件加载路径

private byte[] data = null; //类文件字节码

private String extensionalName = ""; //类文件扩展名

public CustomClassLoader(URL[] urls) throws Exception{

super(urls);

this.url = new String[urls.length];

for (int i = 0; i < urls.length; i++) {

this.url[i] = urls[i].toURI().toString();

}

}

/*

* 解析URL

*/

private void setFilePath() {

for (int i = 0; i < this.url.length; i++) {

if (this.url[i].substring(0,4).toLowerCase().equals("file") == true) {

this.url[i] = this.url[i].substring(5);

}

}

}

/*

* 获得指定类名(包名+类名)文件的字节码

* @name name String

* @return byte[]

*/

private byte[] getFileData(String name) {

try {

this.setFilePath();

for (String url : this.url) {

String fileName = url + name.replace('.', '/').concat(".") +

this.getExtensionalName();

input = new FileInputStream(new File(fileName));

if (input != null) {

break;

}

}

out = new ByteArrayOutputStream();

data = new byte[1024];

int len = -1;

while ((len = input.read(data)) != -1) {

out.write(data, 0, len);

}

data = out.toByteArray();

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

if (input != null)

input.close();

if (out != null)

out.close();

return data;

} catch (Exception e) {

e.printStackTrace();

return null;

}

}

}

/*

* 根据指定类名查找类文件

* @param name String

* @return Class

*/

protected Class findClassByName(String name) {

try {

byte[] data = this.getFileData(name);

if (data == null) {

return null;

}

return this.defineClass(name, data, 0, data.length);

} catch (Exception e) {

e.printStackTrace();

return null;

}

}

/*

* 重写loadClass()方法

* @param name String

* @return Class

*/

public Class loadClass(String name) {

Class c = null;

try {

c = super.loadClass(name);

} catch (ClassNotFoundException e) {

e.printStackTrace();

} finally {

if (c == null) //父类默认方法没有加载到指定类时,使用自定义方法查找

c = this.findClassByName(name);

return c;

}

}

public String getExtensionalName() {

return extensionalName;

}

public void setExtensionalName(String extensionalName) {

this.extensionalName = extensionalName;

}

public static void main(String[] args) throws Exception {

URL[] url = new URL[] {new URL("file:e:/")}; //添加你想要加载类的路径

//网络或本地均可

CustomClassLoader csl = new CustomClassLoader(url);

csl.setExtensionalName("rs");

Class c1 = csl.loadClass("com.demo");

Object obj = c1.newInstance();

Method method = c1.getMethod("printText", null);

method.invoke(obj, null);

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有