黑马程序员——类加载器&代理

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

 类加载器的作用就是将class文件加载到内存中,以实现对其的调用。这是Java中一种特有的机制,所有的类都是通过加载器加载进内存中的,这种方式保证了安全性。

 

 类加载器同时也是一种类,那么它也需要被类加载器加载,这么一直推算下来,总一个有所加载器的父加载器,那么它是如何加载进内存中的呢?这个类就是BootStrap类,它是用C++写的一段程序,不需要使用Java中的类加载器机制,存在于jvm中,当jvm启动的时候,就会自动加载。

 

 可以看出来,加载器一共有三个,父类到子类的关系。分别是:

BootStrap(用C++写的,打印为null),ExtClassLoader,AppClassLoader

验证类加载器机制

public class LoadClassDemo {  
    public static void main(String[] args) {  
        //得到这个类的类加载器   
        ClassLoader loader = LoadClassDemo.class.getClassLoader();  
        //如果父类不为空,就打印父类加载器的名字   
        while (loader != null) {  
            System.out.println(loader.getClass().getName());  
            loader = loader.getParent();  
        }  
        //打印最父类的加载器   
        System.out.println(loader);  
    }  
} 

 


 

这就是3个不同加载器的所加载的内容,BootStrap负责rt.jar包中的东西,ExtClassLoader负责ext文件间下的所有jar包,而AppClassLoader负责classpath指定的有所jar包或者目录。
LoadClassDemo就是由AppClassLoader加载器加载的,当我们自己写一个String类时,是不会被类加载器加载的,因为有个委托机制。
当需要加载一个类的时候,会先寻找其父类加载器,一直从上往下的加载,当找到同名的类时即加载完毕,不会再加载自己写的类。

 

自己写一个类加载器:
我们可以自己写一个类加载器,必须要继承ClassLoader类,这里有2个主要的方法:
1,loadClass()
2,findClass()
 loadClass()负责实现委托机制,不断寻找其父类加载器;
当父类加载器中找不到该类时,执行findClass()中的加载方法。
所以,我们写一个类加载器时,只要覆盖其中的findClass()方法即可,便很容易实现我们自己的类加载器。
如果有特殊需要,我们可以给类加载器加上密钥,只要当使用我们自己的类加载器才能将此类加载进内存

 

 

 

代理

生活中的代理
武汉人从武汉的代理商手中买联想电脑和直接跑到北京传智播客旁边来找联想总部买电脑,你觉得最终的主体业务目标有什么区别吗?基本上一样吧,都解决了核心问题,但是,一点区别都没有吗?从代理商那里买真的一点好处都没有吗?

程序中的代理
要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理、日志、计算方法的运行时间、事务管理、等等,你准备如何做?
编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码。
如果采用工厂模式和配置文件的方式进行管理,则不需要修改客户端程序,在配置文件中配置是使用目标类、还是代理类,这样以后很容易切换,譬如,想要日志功能时就配置代理类,否则配置目标类,这样,增加系统功能很容易,以后运行一段时间后,又想去掉系统功能也很容易

代理架构图

 

交叉业务的编程问题即为面向方面的编程AOP(Object Oriented Programming),AOP的目标就是要交叉业务模块化,可以采用将切面代码移动到原始原始方法的周围,这与直接在方法中编写切面代码的运行效果一样。代理是实现AOP功能的核心和关键技术

 

动态代理技术

要为系统中的各种接口的类增加代理功能,那将需要太多的代理类,全部采用静态代理方式,将是一件非常麻烦的事情!写成百上千个代理类,是不是太累!
JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。
JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。
CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。
代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,还可以在代理方法中的如下四个位置加上系统功能代码:
1.在调用目标方法之前
2.在调用目标方法之后
3.在调用目标方法前后
4.在处理目标方法异常的catch块中

 

代理类的建立,必须得到与需要使用类有关联的代理类的Class文件对象。

通过Proxy.getProxyClass(ClassLoader loader, Class<?>... interfaces);

它必须要接收一个类加载器,和要实现代理接口的Class对象。


既然要使用Proxy这个类,就必须查看其中的构造方法、函数方法。

既然能得到Proxy的Class对象,不妨用反射列出其中的方法,可用如下方法做:

代理类的建立,必须得到与需要使用类有关联的代理类的Class文件对象。

通过Proxy.getProxyClass(ClassLoader loader, Class<?>... interfaces);

它必须要接收一个类加载器,和要实现代理接口的Class对象。


既然要使用Proxy这个类,就必须查看其中的构造方法、函数方法。

既然能得到Proxy的Class对象,不妨用反射列出其中的方法,可用如下方法做:

System.out.println("-------------------Proxy Method-----------------------------");  
        //通过反射返回类中方法数组   
        Method[] methods = clazzProxy.getMethods();  
       for(Method method: methods){  
            String name = method.getName();  
            StringBuilder sb = new StringBuilder(name);  
            sb.append("(");  
            //得到每个方法的参数,通过 getParameterTypes() 方法   
              Class[] clazzParams = method.getParameterTypes();  
            //将参数加入一个StringBuilder,并按照格式打印   
              for(Class clazzParam: clazzParams){  
                sb.append(clazzParam.getName()).append(",");  
            }  
            if(clazzParams.length!=0)  
                sb.deleteCharAt(sb.lastIndexOf(","));  
            sb.append(")");  
            System.out.println(sb.toString());  
        }  

同理得到构造方法,打印结构发现Proxy没有无参构造方法,只有一个有参数构造方法:

com.sun.proxy.$Proxy0(java.lang.reflect.InvocationHandler)  

Proxy类的方法有(包括object类中的方法):

-------------------Proxy Method list -----------------------------  
hashCode()  
equals(java.lang.Object)  
toString()  
add(java.lang.Object)  
contains(java.lang.Object)  
isEmpty()  
size()  
toArray()  
toArray([Ljava.lang.Object;)  
addAll(java.util.Collection)  
iterator()  
remove(java.lang.Object)  
clear()  
containsAll(java.util.Collection)  
removeAll(java.util.Collection)  
retainAll(java.util.Collection)  
isProxyClass(java.lang.Class)  
getProxyClass(java.lang.ClassLoader,[Ljava.lang.Class;)  
newProxyInstance(java.lang.ClassLoader,[Ljava.lang.Class;,java.lang.reflect.InvocationHandler)  
getInvocationHandler(java.lang.Object)  
getClass()  
notify()  
notifyAll()  
wait(long)  
wait(long,int)  
wait()  

 

动态代理的工作原理图

 

 

 

 

内容概要:本文围绕&ldquo;基于分布式模型预测控制的多个固定翼无人机一致性控制&rdquo;展开,利用Matlab代码实现相关算法的仿真,旨在通过分布式控制策略实现多架固定翼无人机在复杂动态环境中的协同飞行与一致性控制。研究结合模型预测控制(MPC)方法,构建适用于多无人机系统的分布式优化框架,重点解决了通信受限、信息延迟及无中心化指挥条件下的协同稳定性问题。内容涵盖固定翼无人机的动力学建模、分布式MPC优化求解机制、一致性协议设计、通信拓扑结构分析以及仿真验证全过程,确保多机系统在保持队形一致的同时完成协同任务。; 适合人群:具备自动控制理论、无人机系统建模或多智能体协同控制基础,从事智能无人系统、集群控制、自动化与机器人等领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于多无人机协同编队飞行、集群侦察、分布式任务执行等实际工程场景;②为分布式MPC算法在多智能体系统中的一致性控制提供可复现的Matlab仿真案例,推动先进控制理论向工程实践转化;③服务于科研论文复现、算法验证、控制系统课程设计与毕业课题参考。; 阅读建议:建议读者结合文中提供的Matlab代码逐模块运行与调试,重点关注分布式MPC在不同通信拓扑下对一致性收敛性能的影响,并可通过调整预测时域、权重矩阵与噪声参数等方式深化对算法鲁棒性与适应性的理解。
内容概要:本文提出了一种基于变分模态分解(VMD)、麻雀搜索算法(SSA)优化与长短期记忆网络(LSTM)相结合的光伏功率预测模型(VMD-SSA-LSTM),旨在提升光伏发电预测的精度与鲁棒性。该方法首先利用VMD对原始非平稳光伏功率序列进行自适应分解,获得一系列具有更稳定特征的本征模态分量(IMFs),有效降低数据复杂性与噪声干扰;随后引入麻雀搜索算法(SSA)对LSTM网络的关键超参数(如学习率、隐层节点数等)进行全局寻优,克服传统试凑法效率低、易陷入局部最优的问题,显著提升模型收敛速度与泛化能力;最后,构建多个LSTM子模型分别预测各模态分量,并将结果重构得到最终的光伏功率预测值。该混合模型充分融合了VMD在信号预处理中的优异分解性能、SSA在参数优化中的高效搜索能力以及LSTM在捕捉时间序列长期依赖关系上的强大建模优势,实现了对复杂气象因素影响下光伏出力波动的高精度拟合与预测。; 适合人群:具备一定电力系统、新能源发电或时间序列预测基础知识,熟悉MATLAB编程环境,从事光伏功率预测、智能电网调度、可再生能源集成、负荷预测等领域研究的科研人员、工程技术人员及高校研究生。; 使用场景及目标:①应用于光伏电站的短期与超短期功率预测,为电网安全调度、电力市场交易、储能系统配置及需求侧响应提供精准数据支撑;②解决传统单一预测模型(如ARIMA、BPNN、单一LSTM)在处理非平稳、强波动性光伏数据时存在的精度不足、稳定性差等问题;③为风电、负荷等其他非平稳时序预测问题提供一种有效的&ldquo;分解-优化-预测&rdquo;混合建模范式与技术实现路径。; 阅读建议:建议读者结合文中提供的完整MATLAB代码,深入理解VMD信号分解、SSA优化算法流程及LSTM网络构建的每一个技术环节,通过实际历史数据进行模型复现与对比实验(如与VMD-LSTM、SSA-LSTM等模型比较),掌握参数调优技巧与模型性能评估方法,从而真正掌握该先进混合预测模型的核心思想与应用精髓。
代码转载自:https://pan.quark.cn/s/a4b39357ea24 在当代信息技术行业,深度学习技术的应用已经全面渗透到众多实际情境中,其中生成对抗网络(GAN)以及深度卷积生成对抗网络(DCGAN)被视为促进人工智能领域发展的核心技术之一。接下来将具体阐述如何借助Pytorch框架与MNIST数据集来完成基础GAN和DCGAN的开发,并解析过程中涉及的关键概念。 ### Pytorch框架与MNIST数据集概述 **Pytorch** 被视为一种广受欢迎的开源机器学习平台,其具备动态计算图与高度适应性等特性,因此在学术研究领域备受推崇,能够支持多种类型的深度学习架构。 **MNIST数据集** 是一个包含手写数字的图像集合,常用于训练各类图像识别系统,涵盖从0至9的数字图像,每张图像的尺寸为28x28像素。由于其入门级难度,MNIST数据集特别适合用于教学演示和实验操作。 ### 基础生成对抗网络(GAN)核心概念 **基础GAN** 是一种由生成器(Generator)和判别器(Discriminator)构成的无监督学习框架。生成器的核心任务是创造足以乱真的图像数据,而判别器的关键职责在于精确辨别真实图像与生成图像之间的差异。 1. **生成器**:该模块以随机噪声为输入,通过深度神经网络进行转换,最终输出接近真实图像的数据。其根本目的在于迷惑判别器。 2. **判别器**:对输入数据(无论是真实图像还是生成图像)进行评估,并输出其属于真实样本的概率。判别器的训练重点在于提升识别的精确度。 3. **训练机制**:GAN的训练过程涉及两个网络之间的交替训练,即在锁定一个网络参数的情况下对另一个网络进行训练。首先优化判别器以增强其区分能力...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值