黑马程序员_类加载器知识总结

本文详细介绍了Java类加载器的工作原理,包括类加载器的作用、本质及类加载过程中的委托机制。通过实例演示如何自定义类加载器并探讨了类加载器在实际应用中的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



------------------------------------------------android培训java培训期待与您交流!-----------------------------------------------

类加载器的作用

把存放在硬盘里面类的字节码加载到内存里面来,然后再对其进行处理

类加载器本质

它也是Java类,第一个类加载器不是java类,是BootStrap(它是由C++写的一段程序)。

类加载器原理

因为类加载器采用的是委托机制,委托机制的原理就是,
当某一个类的字节码要加载到内存来的时候,首先让最
上级的那个类加载器来加载,如果说最上级类加载器没
有加载到该类的字节码那么就让下一级类加载器对其进
行加载也就是说如果所有祖宗类加载器都没有加载到类,
回到发起者类加载器,还加载不了,那么抛ClassNotFoundException

 


由图可知在比方说加载CLASSPATH指定的所有jar或目录里面的类的时候,
首先找BootStrap从JRE/lib/rt.jar目录下加载没有找到该类再交给
ExtClassLoader从JRE/lib/ext/*.jar目录下加载,还没有加载到类,
那么就再交给发起者类加载器AppClassLoader从CLASSPATH指定的所有
jar或目录里面加载对应的类,没有加载到得话就报错

 

出现的问题:

①为什么每个类加载器加载类时,要先委托给其上级类加载器

因为为了集中管理,如果交给其他的类加载器,比方说A类加载器在加载
Systemt时加载到了一个system,B类加载器加载Systemt时加载也加载到了
一个system那么内存中就出现了两份字节码,会出现多份字节码重复的现象

②如果自己写一个system类会不会被加载

通常不可以因为委托机制BootStrap首先就从rt.jar包中加载到了system
根本就不会加载自己写的那个system,如果硬要找自己的system可以自己
写一个类加载器并且撇开委托加载机制

编写自己的类加载的方法(用的伪代码实现)

①首先定义一个类继承ClassLoader,并且重写其findClass方法

public class MyClassLoader extends ClassLoader
	{

		public MyClassLoader()
		{
		}

		public MyClassLoader(String classDir)
		{
			this.classDir = classDir;
		}

		@Override
		protected Class<?> findClass(String name)
		{
			// 这里根据name然后理由流操作从磁盘中读取文件然后对其进行操作
			// 之后得到其文件的字节信息最后用defineClass得到该类的字节码
			// byte[] bytes = bos.toByteArray();
			// return defineClass(bytes, 0, bytes.length);
		}
	}

②其次写一个要被自己写的类加载器加载的类

public class ClassLoaderAttachment extends Date
	{
		public String toString()
		{
			return "helloworld";
		}
	}


③最后写一个测试类

Class clazz = new MyClassLoader("mylib").loadClass("ClassLoaderAttachment");

Date d1 =  (Date)clazz.newInstance();

由自己编写的类加载器引出的思考

①为什么上面的ClassLoaderAttachment要继承Date对象

因为Class clazz = new MyClassLoader("itcastlib").loadClas("ClassLoaderAttachment");
ClassLoaderAttachment d1 =  (ClassLoaderAttachment)clazz.newInstance();
编译器在调用第二句执行语句的时候,编译器会从自己的类加载器中加载该类,
而我们已经把相应类加载里面的字节码替换为自己加密了的字节码,所以编译器
无法解析我们自己加密了的字节码就会报错,而Date我们没有改变所以编译器可以解析

②模版方法在类加载器里面的运用

模版方法的特征:
ⓐ父类具有统一的操作步骤或操作过程
ⓑ子类实现具有不同的操作细节
ⓒ存在多个具有同样操作步骤的应用场景,但某些具体的操作细节却各不相同
而类加载器也是这样,子类加载器加载不同的类可能方法不同,但是总的流程都是一样的,子类加载器先找父类加载器加载相关的类,没有在找自己(细节)


//主类
public abstract class MakeCar {
	//组装车头
	public abstract void makeHead();
	//组装车身
	public abstract void makeBody();
	//组装车尾
	public abstract void makeTail();
	//把主题的流程已经给规定好了
	public void make() {
		this.makeHead();
		this.makeBody();
		this.makeTail();
	}
}
public class MakeJeep extends MakeCar {//子类继承父类,实现细节
	public void makeBody() {
		System.out.println("jeep:组装车身");
	}
	public void makeHead() {
		System.out.println("jeep:组装车头");
	}
	public void makeTail() {
		System.out.println("jeep:组装车尾");
	}

}
//测试类
public class MainClass {
	public static void main(String[] args) {
		MakeCar jeep = new MakeJeep();
		jeep.make();//只需调用父类的哪个固定封装好了的流程
	}
}

③Tomcat类加载器的高级问题分析总结

如果类加载器MyClassLoader负责加载A类,A类引用了B了类,而B类却不是放在MyClassLoader指定的目录下或者说不由MyClassLoader负责加载那么运行的时候就会报错,因为MyClassLoader加载A类的时候找不到类B。

----------------------------------------- android培训java培训、java学习型技术博客、期待与您交流! --------------------------


详情请查看:http://edu.youkuaiyun.com/heima
















资源下载链接为: https://pan.quark.cn/s/f989b9092fc5 HttpServletRequestWrapper 是 Java Servlet API 中的一个工具类,位于 javax.servlet.http 包中,用于对 HttpServletRequest 对象进行封装,从而在 Web 应用中实现对 HTTP 请求的拦截、修改或增强等功能。通过继承该类并覆盖相关方法,开发者可以轻松地自定义请求处理逻辑,例如修改请求参数、添加请求头、记录日志等。 参数过滤:在请求到达处理器之前,可以对请求参数进行检查或修改,例如去除 URL 编码、过滤敏感信息或进行安全检查。 请求头操作:可以修改或添加请求头,比如设置自定义的 Content-Type 或添加认证信息。 请求属性扩展:在原始请求的基础上添加自定义属性,供后续处理使用。 日志记录:在处理请求前记录请求信息,如 URL、参数、请求头等,便于调试和监控。 跨域支持:通过添加 CORS 相关的响应头,允许来自不同源的请求。 HttpServletRequestWrapper 通过继承 HttpServletRequest 接口并重写其方法来实现功能。开发者可以在重写的方法中添加自定义逻辑,例如在获取参数时进行过滤,或在读取请求体时进行解密。当调用这些方法时,实际上是调用了包装器中的方法,从而实现了对原始请求的修改或增强。 以下是一个简单的示例,展示如何创建一个用于过滤请求参数的包装器: 在 doFilter 方法中,可以使用 CustomRequestWrapper 包装原始请求: 这样,每当调用 getParameterValues 方法时,都会先经过自定义的过滤逻辑。 HttpServletRequestWrapper 是 Java Web 开发中一个强大的工具,它提供了灵活的扩展性,允许开发者
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值