java 自定义的类加载器_Java如何自定义类加载器[通俗易懂]
我们可以编写自己的用于特殊目的的类加载器,这使得我们可以在向虚拟机传递字节码之前执行定制的检查。
如何自定义类加载器
如果想要编写自己的类加载器,只需要两步:
继承ClassLoader类
覆盖findClass(String className)方法
ClassLoader超类的loadClass方法用于将类的加载操作委托给其父类加载器去进行,只有当该类尚未加载并且父类加载器也无法加载该类时,才调用findClass方法。
如果要实现该方法,必须做到以下几点:
1.为来自本地文件系统或者其他来源的类加载其字节码。
2.调用ClassLoader超类的defineClass方法,向虚拟机提供字节码。
下面是自定义类加载器的一种实现方式:
public class CustomClassLoader extends ClassLoader {
protected Class> findClass(String name) throws ClassNotFoundException {
try {
String cname = “/Users/wuzhenyu/Desktop/spring-boot/src/main/java/” + name.replace(‘.’, ‘/’) + “.class”;
byte[] classBytes = Files.readAllBytes(Paths.get(cname));
Class> cl = defineClass(name, classBytes, 0, classBytes.length);
if (cl == null) {
throw new ClassNotFoundException(name);
}
return cl;
} catch (IOException e) {
System.out.print(e);
throw new ClassNotFoundException(name);
}
}
}
我在该类的目录下准备了一个编译好的类文件SayHello.class(后缀改为了text),SayHello.class对应的Java代码如下:
public class SayHello {
public static void main(String[] args) {
System.out.print(“Hello World”);
}
}
下面是测试类的代码:
测试前请删除SayHello.java文件
public class ClassLoaderTest {
public static void main(String[] args) {
try {
ClassLoader loader = new CustomClassLoader();
//调用loadClass加载sample.loader.SayHello类
//无法加载到该类,因此会调用findClass方法
Class> c = loader.loadClass(“sample.loader.SayHello”);
Method m = c.getMethod(“main”, String[].class);
m.invoke(null, (Object) new String[]{});
} catch (Throwable e) {
System.out.println(e);
}
}
}
运行结果如下:
Hello World
这是一个简单的实现自己类加载器的例子。在更复杂的案例中,使用的往往是加密过的类文件,加载该类字节码时,还需要解密。不然它们就不能由标准虚拟机来执行,也不能轻易被反汇编。
类加载器相关的API
1. java.lang.Class
ClassLoader getClassLoader(): 获取加载该类的类加载器
2.java.lang.ClassLoader
ClassLoader getParent():返回父类加载器,如果父类加载器是引导类加载器,则返回null。
static ClassLoader getSystemClassLoader():获取系统类加载器,即用于加载第一个应用类的类加载器。
protected Class findClass(String name):类加载器应该覆盖该方法,以查找类的字节码,并通过调用defineClass方法将字节码传给虚拟机。在类的名字中,使用.作为包名分隔符,并且不使用.class后缀。
Class definedClass(String name, byte[] byteCodeData, int offset, int length):将一个新的类添加到虚拟机,其字节码在给定的数据范围中。
3.java.net.URLClassLoader
URLClassLoader(URL[] urls)
URLClassLoader(URL[] urls, ClassLoader parent) :构建一个类加载器,它可以从给定的URL处加载类。如果URL以 / 结尾,那么它表示的一个目录,否则,它表示的是一个JAR文件。
4.java.lang.Thread
ClassLoader getContextClassLoader():获取类加载器,该线程的创建者将其指定为执行该线程时最适合使用的类加载器。
void setContextClassLoader(ClassLoader loader):为该线程中的代码设置一个类加载器,以获取要加载的类。如果在启动一个线程时没有显式地设置上下文类加载器,则使用父线程的上下文类加载器。
参考文献《Java 核心技术 卷二》
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
相关文章
- 数据透视表上线!如何在纯前端实现这个强大的数据分析功能?
- Java设置全局变量_java如何定义全局变量
- 如何让pycharm运行Java代码[通俗易懂]
- ajax请求的五个步骤java_如何发送ajax请求?ajax请求的五个步骤详解[通俗易懂]
- java退出foreach循环_forEach方法如何跳出循环[通俗易懂]
- java指定长度数组长度_Java声明数组时不能指定其长度[通俗易懂]
- java pfx_如何在Java中读取.pfx文件的内容?
- java 二维数组 arraycopy_Java对数组的复制[通俗易懂]
- Java商城源码最好用的java商城电商系统之一
- java开发常用四大框架_Java 后台开发框架[通俗易懂]
- java google 离线地图开发_如何发布google离线地图及二次开发API[通俗易懂]
- java 舆情分析_基于Java实现网络舆情分析系统研究与实现.doc[通俗易懂]
- Java cloneable_java浅克隆和深克隆
- 学习如何使用Linux环境运行Java程序(linux下的java)
- 使用Java操作Redis数据库(java中使用redis)
- Java程序员如何优雅操作Redis(java操作redis)
- 如何在Linux系统下有效地启动Java程序,让你的代码在Linux中也能正常运行?(linux下启动java)
- Java如何启动MySQL?(java启动mysql)
- Java开发者如何快速掌握Neo4j(java操作neo4j)
- 数据库一步一步教你Java如何恢复Oracle数据库(java恢复oracle)