java 自定义的类加载器_Java如何自定义类加载器[通俗易懂]

java 自定义的类加载器_Java如何自定义类加载器[通俗易懂]我们可以编写自己的用于特殊目的的类加载器,这使得我们可以在向虚拟机传递字节码之前执行定制的检查。如何自定义类加载器如果想要编写自己的类加载器,只需要两步:继承ClassLoader类覆盖findClass(StringclassName)方法ClassLoader超类的loadClass方法用于将类的加载操作委托给其父类加载器去进行,只有当该类尚未加载并且父类加载器也无法加载该类时,才调用fin…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

我们可以编写自己的用于特殊目的的类加载器,这使得我们可以在向虚拟机传递字节码之前执行定制的检查。

如何自定义类加载器

如果想要编写自己的类加载器,只需要两步:

继承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 核心技术 卷二》

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196723.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • apache 负载均衡_apache部署

    apache 负载均衡_apache部署[1]Apache负载均衡设置方法mod_proxy使用介绍一般来说,负载均衡就是将客户端的请求分流给后端的各个真实服务器,达到负载均衡的目的。还有一种方式是用两台服务器,一台作为主服务器(Master),另一台作为热备份(HotStandby),请求全部分给主服务器,在主服务器当机时,立即切换到备份服务器,以提高系统的整体可 第一次看到这个标题时我也很惊讶,Apache居然还能做负载

    2022年9月9日
    1
  • webstorm2021激活码_通用破解码

    webstorm2021激活码_通用破解码,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月17日
    273
  • python读写json_python格式化json

    python读写json_python格式化jsonJSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。JSON在python中分别由list和dict组成。这是用于序列化的两个模块:json:用于字符串和p

    2022年8月31日
    0
  • 开源项目之架构分享[通俗易懂]

    开源项目之架构分享[通俗易懂]此次分享是我当初在开发某个系统时,参考的一些开源项目架构的思路和风格。第一个是Jeesite,它的架构风格如下:大家如果对jeesite感兴趣的话,可以百度搜索找到,不过那已经是半年多以前的事情,jeesite目前也发生较大的变化。当初我在参考jessite这个思路时,不知道是什么原因使我没有加入module,其实从现在的角度出发,加上module也是一件不错的事情,modu…

    2022年7月28日
    5
  • c语言-日期格式化[通俗易懂]

    c语言-日期格式化[通俗易懂]7-12日期格式化(5分)世界上不同国家有不同的写日期的习惯。比如美国人习惯写成“月-日-年”,而中国人习惯写成“年-月-日”。下面请你写个程序,自动把读入的美国格式的日期改写成中国习惯的日期。输入格式:输入在一行中按照“mm-dd-yyyy”的格式给出月、日、年。题目保证给出的日期是1900年元旦至今合法的日期。输出格式:在一行中按照“yyyy-mm-dd”的格式给出年…

    2022年6月9日
    45
  • python for循环多个参数处理_python for循环嵌套

    python for循环多个参数处理_python for循环嵌套实际上,“使用for循环遍历数组的最简单方法”(Python类型被命名为“list”BTW)是第二种方法,即foriteminsomelist:do_something_with(item)哪个FWIW适用于所有iterable(列表、元组、集合、dict、迭代器、生成器等)。基于范围的C风格版本被认为是非常不通俗的,并且只适用于列表或类似列表的iterable。WhatIwouldl…

    2022年8月12日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号