实现功能:从文件或 InputStream 中加载一个类到内存中,并可以正常调用该类的方法.
// org.future.StreamClassLoader.java
package org.future.loader;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
*@date 2010-3-27 下午08:34:20
*@author dycc
*@file org.future.StreamClassLoader.java
*/
public class StreamClassLoader extends ClassLoader{
// 当前类的一个实例
private static StreamClassLoader instance;
/**
* 构造方法设为私有的
*/
private StreamClassLoader(){
}
/**
* 返回当前类的一个实例
* @return
*/
public static StreamClassLoader getInstance(){
if(instance == null){
instance = new StreamClassLoader();
}
return instance;
}
/**
* 从文件中加载一个类
* @param filePath 例: D:/temp/classes/AppleTree.class
* @param className 例: org.future.locale.AppleTree
* @return The Class object that was created from the specified file.
*/
@SuppressWarnings(value="unchecked")
public Class load(String filePath,String className)
throws FileNotFoundException,IOException{
FileInputStream in = new FileInputStream(filePath);
return load(in,className);
}
/**
* 从流中加载一个类
* @param in
* @param className 例: org.future.locale.AppleTree
* @return The Class object that was created from the specified inputStream.
*/
@SuppressWarnings(value="unchecked")
public Class load(InputStream in,String className)throws IOException{
// 如果该类已经被加载过则直接返回
Class cls = this.findLoadedClass(className);
if(cls != null){
return cls;
}
// 从流中读取所有的字节
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] data = new byte[1024];
int len = -1;
while((len = in.read(data, 0, data.length)) > 0){
out.write(data, 0, len);
}
data = out.toByteArray();
in.close();
out.close();
// 调用父类方法从字节数组中加载类
return defineClass(className, data, 0, data.length);
}
}
// 测试类:org.future.loader.StreamClassLoaderTest.java
package org.future.loader;
/**
*@date 2010-3-27 下午08:53:25
*@author dycc
*@file org.future.loader.StreamClassLoaderTest.java
*/
public class StreamClassLoaderTest {
@SuppressWarnings(value="unchecked")
public static void main(String[] args)throws Exception {
String filePath = "D:/eclipse/workspace/Test/build/classes/AppleTree.class";
String className = "org.future.locale.AppleTree";
StreamClassLoader loader = StreamClassLoader.getInstance();
Class cls = loader.load(filePath, className);
Tree tree = (Tree)cls.newInstance();
System.out.println("name=" + tree.getName());
System.out.println("height=" + tree.getHeight());
cls = loader.load(filePath, className);
tree = (Tree)cls.newInstance();
System.out.println("name=" + tree.getName());
System.out.println("height=" + tree.getHeight());
}
}
// 一个接口:org.future.loader.Tree.java
package org.future.loader;
/**
*@date 2010-3-27 下午08:57:09
*@author dycc
*@file org.future.loader.Tree.java
*/
public interface Tree {
/**
* 名称
* @return
*/
public String getName();
/**
* 高度
* @return
*/
public int getHeight();
}
// 一个实现类:org.future.locale.AppleTree.java
package org.future.locale;
import org.future.loader.Tree;
/**
*@date 2010-3-27 下午08:59:42
*@author dycc
*@file org.future.locale.AppleTree.java
*/
public class AppleTree implements Tree{
// 获取名称
public String getName() {
return "Apple Tree";
}
// 获取高度
public int getHeight() {
return 3;
}
}
分享到:
相关推荐
自定义Classloader允许开发者根据特定需求定制类的加载逻辑,例如加密类文件、隔离不同版本的库或者动态加载代码。本文将深入探讨自定义Classloader的使用。 一、Classloader的工作原理 Java的类加载机制遵循双亲...
让Java支持热加载是个不错的想法。如何做到的呢? 1. 定义好接口和实现类 2. 让代理类通过反射的方式调用实现类,对外暴露的是代理类。 3. 自定义URLClassLoader。检查实现类.class文件的...Java自定义classloader;
当我们需要从外部jar包动态加载类时,自定义ClassLoader就显得尤为关键。这篇博文"定义ClassLoader调用外部jar包"探讨了如何创建一个自定义的ClassLoader,以便能够灵活地加载不在应用主类路径(ClassPath)中的jar...
这里我们将详细讨论ClassLoader的运行机制,特别是自定义ClassLoader的设计与实现。 ClassLoader的基本职责是根据类名动态加载对应的类文件。在Java中,类加载过程遵循双亲委派模型(Parent Delegation Model)。这...
标题和描述中提到的解决方案是通过自定义`ClassLoader`来处理`serialVersionUID`不一致的问题。以下是几种常见方法的优缺点以及自定义`ClassLoader`的详细解释: 1. **修改序列化byte数据**: 这种方法直接修改已...
在Android开发中,自定义ClassLoader是一项关键技能,尤其在实现热修复和插件化技术时。本文主要探讨了Android中自定义ClassLoader导致的性能问题,特别是冷启动速度的影响。问题的核心在于,通过插入自定义的...
自定义 ClassLoader 加载任何类时的类名。 ":myCommand" 命令位于默认 REPL 命令之上。 scala > val hello = " hello " MyClassLoader loads classOf < root>.$line3 <<中略>> MyClassLoader loads classOf ...
自定义ClassLoader允许开发者根据特定需求加载类,比如动态加载或更新类文件,这在某些高级应用场景中非常有用,如插件系统、热部署等。本案例将深入探讨如何创建一个自定义的ClassLoader,利用Java反射和注解技术...
下面我们将详细讨论ClassLoader的基本概念、工作流程以及如何自定义ClassLoader。 1. **ClassLoader的基本概念** - 类加载器是Java中的一个核心组件,它负责将类的.class文件加载到JVM中,并转换为可执行的Java...
创建自定义类加载器需要继承ClassLoader类,并重写findClass()方法。在这个方法里,你可以编写代码来从指定的位置(例如,网络、文件系统或内存)读取类的字节码,并通过defineClass()方法将其转换为Class对象。 在...
在某些特定场景下,比如动态加载代码、插件系统或者安全隔离等,我们需要自定义ClassLoader来实现特定的加载逻辑。例如,我们可能希望加载网络上的类,或者从数据库中读取类的字节码。 以...
为了更好地理解和利用Java的这一特性,本篇将详细介绍Java ClassLoader的作用及其工作原理,并通过构建一个示例ClassLoader来帮助读者深入理解如何自定义ClassLoader,从而扩展JVM的功能。 #### 二、ClassLoader...
了解和掌握ClassLoader的工作原理以及如何自定义ClassLoader对于深入理解Java应用程序的运行机制非常有帮助。以下是对ClassLoader API的使用和自定义的详细说明。 首先,我们来看ClassLoader的基本概念。在Java中,...
但有时我们可能需要打破这种模型,比如实现类的版本控制或插件系统,这时可以通过自定义ClassLoader来实现。 5. 类加载器的关系图 Java中的ClassLoader形成了一个树状结构,Bootstrap ClassLoader位于顶端,其他类...
自定义ClassLoader是一种常见的需求,例如在插件系统、热部署等场景。自定义加载器通常需要重写`loadClass(String className)`方法,通过URL读取类的字节流并转换为Class对象。在这个过程中,我们需要注意类的缓存,...
自定义ClassLoader需要继承`java.lang.ClassLoader`类,并重写`findClass()`或`loadClass()`方法。通过这两个方法,你可以控制类的加载来源和方式。 在实际开发中,理解ClassLoader机制可以帮助解决一些问题,例如...
自定义ClassLoader是Java平台的一大特色,开发人员可以根据需要创建自己的类加载器,例如实现模块化、热部署或者加密解密类等高级功能。自定义ClassLoader通常需要重写findClass()或loadClass()方法,以控制类的加载...
在Java中,用户可以通过自定义ClassLoader来实现特定的加载逻辑,比如从数据库或网络中加载类。这使得Java可以支持许多高级功能,例如插件系统、热部署和模块化系统(如Java 9的Jigsaw项目)。 `JAVA2深度历险.jpg`...
1. 自定义需求:在某些场景下,如动态加载插件、加密类文件等,开发者可能需要自定义ClassLoader。自定义ClassLoader需要继承java.lang.ClassLoader并重写findClass()方法。 2. 实现步骤:创建类加载器实例,读取类...