自定义加载器<code>
3个类LoaderTest01.java, LoaderTest02.java,MyClassLoader.java
1, MyClassLoader
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class MyClassLoader extends ClassLoader{
private String name;
private String path;
private final String fileType=".class";
public MyClassLoader(String name){
super();
this.name=name;
}
public MyClassLoader(ClassLoader parent,String name){
super(parent);
this.name=name;
}
@Override
public String toString() {
return this.name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getFileType() {
return fileType;
}
private byte[] loadClassData(String name) {
InputStream in=null;
byte [] data=null;
ByteArrayOutputStream bs=null;
try{
System.out.println("name="+this.name);
this.name=this.name.replace(".", "\\");
in=new FileInputStream(new File(path+name+fileType));
bs=new ByteArrayOutputStream();
int k=0;
while((k=in.read())!=-1){
bs.write(k);
}
data=bs.toByteArray();
}catch(Exception e){
e.printStackTrace();
}finally{
try {
in.close();
bs.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return data;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte [] data=this.loadClassData(name);
return this.defineClass(name, data, 0,data.length);
}
public static void main(String args[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
MyClassLoader loader01=new MyClassLoader("loader01");
loader01.setPath("d:\\loader\\lib1\\");
MyClassLoader loader02=new MyClassLoader(loader01,"loader02");
loader02.setPath("d:\\loader\\lib2\\");
MyClassLoader loader03=new MyClassLoader(null,"loader03");
loader03.setPath("d:\\loader\\otherlib3\\");
load(loader02);
load(loader03);
}
public static void load(ClassLoader loader) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
Class c=loader.loadClass("LoaderTest01");
Object object=c.newInstance();
}
}
2, LoaderTest01
public class LoaderTest01 {
public LoaderTest01() {
System.out.println("LoaderTest01 is loader by :"+this.getClass().getClassLoader());
new LoaderTest02();
}
}
3, LoaderTest02
public class LoaderTest02 {
public LoaderTest02() {
System.out.println("LoaderTest02 is loader by :"+this.getClass().getClassLoader());
}
}
第一种情况文件按照下面位置放置
运行结果如下:
分析:当执行load(loader02)这句语句的时候,会优先去找它的父加载器loader01, 而loader01又回去找它的父类是系统加载器,系统加载器会根据classpath来查找所要加载的类,发现没有,接着由loader01去加载,loader01加载的时候找到文件执行接下操作,而LoaderTest01里主动使用了new LoaderTest02(), LoaderTest02也会根据上面的方式去找,跟LoaderTest01结果是一样的。
当执行load(loader03)这句语句的时候,由于父类加载器是null默认为根加载器,根加载器会去sun.boot.class.path的里面去找没有找到,最后由loader3自己去加载。
第二种情况文件按照下面位置放置
运行结果如下:
分析:当执行load(loader02)的时候,会优先去找它的父加载器loader01, 而loader01又回去找它的父类是系统加载器,系统加载器会根据classpath来查找所要加载的类,发现没有,接着由loader01去加载,loader01加载的时候找到文件执行接下操作,而LoaderTest01里主动使用了new LoaderTest02(), LoaderTest02也会执行上面同样的步骤, 但是LoaderTest01和LoaderTest02位于2个不同的加载器空间下,而他们之间是互相不可见的(他们的父子关系并不是继承,也有可能是组合,但是他们都是系统加载器的子类,对系统加载器里的资源都是共享的),所以在Loader01加载器加载的时候无法获取LoaderTest02
第三种情况:
运行结果如下:
分析:当执行load(loader02)的时候,会优先去找它的父加载器loader01, 而loader01又回去找它的父类是系统加载器,系统加载器会根据classpath来查找所要加载的类,并在当前目录下发现了这2个类,并执行操作,前2个加载器均为系统加载器,虽然lib1和lib2下2个文件在不同的类加载器空间下,但是实际执行并不需要它们,在系统一级已经执行完毕,而第三个,当执行load(loader03)的时候,父加载器null默认为根加载器,根加载器无法在相应的目录里找到相应的文件,于是交由其他加载器实现,而此时loader03加载器在相应的otherlib3下也无法找到相应的文件于是报错。
- 大小: 14.8 KB
- 大小: 3 KB
- 大小: 16.3 KB
- 大小: 6.5 KB
- 大小: 16.9 KB
- 大小: 3.9 KB
分享到:
相关推荐
在Java编程语言中,类加载器(ClassLoader)是运行时环境...理解类加载机制并正确实现自定义加载器是提升Java应用开发能力的重要一步。在实际项目中,合理利用类加载器可以解决很多复杂问题,比如模块化、动态更新等。
- **安全沙箱**:每个加载器都有自己的命名空间,可以通过自定义加载器限制代码访问权限。 - **插件系统**:插件有自己的类加载器,使得插件可以独立于主程序加载和卸载。 在编写`MyClassLoader`时,需要注意的是,...
在Java虚拟机(JVM)中,字节码自动加载是一项关键...总之,JVM字节码自动加载是一个涉及类加载器、双亲委派模型以及字节码解析和验证的复杂过程。掌握这些知识有助于我们更好地理解和调试Java应用程序,提升开发效率。
2. 安全性问题:如果允许用户自定义类加载器任意加载代码,可能会破坏系统的安全策略,因为类加载器可以加载不受限制的代码。 3. 单例模式的实现:在多线程环境中,如果每个线程都有自己的类加载器,可能导致单例...
综上所述,JVM的类加载器子系统是复杂且精细的,它涉及到了类的加载、验证、准备、解析和初始化等多个环节。而类加载器作为类加载过程中的关键组件,其设计使得Java应用程序能够灵活地加载和运行各种不同的类文件。...
例如,当我们尝试加载 `java.lang.Object` 类时,首先会由启动类加载器加载,如果它找不到,会继续交给扩展类加载器,接着是系统类加载器,最后才会由用户自定义的类加载器尝试加载。 1.3 类加载双亲委派示例 为了...
2. **类加载器及类加载器的委托机制**:JVM中有三种内置的类加载器,分别是启动类加载器、扩展类加载器和应用类加载器。此外,还可以自定义类加载器。类加载器之间遵循委托机制,即下级类加载器先请求上级类加载器...
在Java中,类加载器是负责加载类到JVM(Java虚拟机)的核心组件。自定义类加载器允许开发者根据特定需求定制类的加载逻辑,例如在加载过程中进行加密、混淆等操作,以增加程序的保护层。 本文将深入探讨Java加壳...
Java程序的运行依赖于类加载器将`.class`文件加载到JVM中,并对其进行验证、准备和解析等步骤,最终使类能够在JVM中执行。 #### 三、Class文件的加载过程 Java类的加载过程主要可以分为以下几个阶段: 1. **加载...
《JAVA-JVM-01类加载机制》 Java虚拟机(JVM)是Java程序运行的基础,其中类加载机制是其核心组成部分。...自定义类加载器则提供了扩展JVM类加载功能的可能,使得开发者能够根据需求加载非标准路径或网络上的类。
JVM(Java虚拟机)采用“双亲委派模型”加载类,即当一个类被加载时,它会首先尝试由启动类加载器(Bootstrap ClassLoader)加载,如果该类不在启动类加载器的路径中,则会委托给扩展类加载器(Extension ...
Java 类加载器是 Java 运行时环境中不可或缺的组成部分,负责将 .class 文件加载到 JVM 中。理解类加载器的工作原理对于深入掌握 Java 语言及其运行机制至关重要。本文将详细探讨 Java 类加载器的概念、类型以及工作...
在Java编程语言中,类加载器(ClassLoader)是运行时环境的重要组成部分,它负责查找和加载类的字节码文件到Java虚拟机(JVM)中。本篇将深入探讨自定义类加载器的实现、双亲委派模型以及如何指定父类加载器。 首先...
- **特点**:如果应用程序中没有自定义类加载器,通常就是使用此加载器。 #### 六、示例代码解析 以下是一个简单的示例代码,演示了如何获取不同级别的类加载器: ```java @Test public void testClassLoader1()...
类加载器是Java虚拟机(JVM)的重要组成部分,它负责将类的字节码从文件系统或网络中加载到JVM中,并转换为运行时的java.lang.Class对象。类加载器不仅涉及程序的启动,还关系到类的动态加载、类间的隔离以及安全性...
用户可以通过自定义类加载器来控制字节流的获取方式,增加了程序的灵活性。 2. **验证(Verification)**: 验证阶段是链接过程的第一步,目的是确保加载的类文件信息符合JVM规范且不会危害虚拟机的安全。验证包括...
《JVM Profiler:深入解析与应用》 在IT领域,优化Java应用程序的性能是至关重要的,而JVM(Java虚拟机)作为Java程序运行的基础,其内部运作机制的了解和调优对于提升效率至关重要。"jvm-profiler"是一个开源项目...
四、自定义类加载器 开发者可以通过继承java.lang.ClassLoader类来创建自己的类加载器,实现特定的加载策略。例如,可以从网络上加载类,或者实现热部署等高级功能。 五、类加载的工具与实践 在Java开发中,类...
Java的类加载器是Java虚拟机(JVM)的核心组件之一,它负责将类的字节码文件从文件系统或网络中加载到JVM中,然后进行校验、解析和初始化,使得Java程序能够运行。类加载器的概念是Java动态加载和运行时类重定义的...