反射和代理

简介: 反射和代理

一、反射

1、概述

反射是允许在运行态动态生成Object对象,能够通过类Class信息获取属性、方法、注解,并能够动态调用,能够动态调用对象方法的机制。


2、获取Class对象

通过以下方式获取到Class对象:


通过对象的getClass()方法。

通过类的class成员变量。

通过Class类的forName()方法。

Studentstudent=newStudent();
//1. 通过对象的getClass()方法。Class<?extendsStudent>clazz=student.getClass();
//2. 通过类的class成员变量。Class<Student>clazz1=Student.class;
//3. 通过Class类的forName()方法。Class<?>clazz2=Class.forName("reflect.reflect.Student");


3、创建对象

通过以下方式创建对象:

//调用方法:clazz.newInstance()Studentstudent1=clazz.newInstance();
//获取构造器后调用方法:constructor.newInstance()Constructor<?extendsStudent>constructor=clazz.getConstructor();
Studentstudent2=constructor.newInstance();

通过以下方式获取属性、方法和注解:

//获取属性Field[] fields=clazz.getDeclaredFields();
for (Fieldfield : fields) {
System.out.println(field.getName());
}
//获取方法Method[] methods=clazz.getDeclaredMethods();
for (Methodmethod : methods) {
System.out.println(method.getName());
Class<?>[] types=method.getParameterTypes();
if (types!=null&&types.length>0) {
System.out.println(types[0].getName());
    }
}
//获取注解Annotation[] annotations=clazz.getDeclaredAnnotations();
for (Annotationannotation : annotations) {
System.out.println(annotation.annotationType().getSimpleName());
}


4、总结

反射的优点:


能够再运行态动态获取类的属性、方法和注解信息,能够动态生成对象。

反射的缺点:


破坏了类的封装性,通过反射能够读取private的属性、方法。

二、代理

代理是一种设计模式,作用是在不扩张目标对象的前提下,通过扩展代理类来对目标对象的功能进行增强。其模型为访问者通过代理对象来访问目标对象。一般包括代理对象、目标对象、目标对象接口三种角色。



1、静态代理

静态代理是在编译期就已经在代理类中确定了目标对象要扩展的功能,无法在运行态动态生成代理对象,灵活性不够。


代码实现 https://github.com/yangnk/JavaHelloworld/tree/master/src/main/java/reflect/proxy


2、动态代理

动态代理可以在运行态动态生成代理对象,适用于在运行态目标对象会灵活生成的。


(1)JDK原生动态代理

实现方法:原生的JDK动态代理重点是实现InvocationHandler接口,需要你重写invoke()方法,在这个方法里将需要增强的部分增强就好了。

实现原理:通过Proxy.newProxyInstance()方法创建实现InvocationHandler接口的invoke()方法,底层是通过反射来做到的。

(2)CgLib动态代理

实现方法:这个是第三方lib实现,需要引入cglib库,首先还是需要实现MethodInterceptor接口,重写其中的intercepter()方法,这个看起来和JDK 原生动态代理差不多。

(3)总结

JDK动态代理和CgLib动态代理区别:


JDK Proxy在原生JDK中即可实现,通过实现InvocationHandler接口即可,他的原理是通过反射生成目标类的匿名类;而CgLib Proxy需要引入第三方包,他是通过asm来操作字节码,生成目标类的子类,在运行时将该子类的字节码加载进来。

JDK proxy作为代理类,需要目标类有接口才能代理实现,即只能针对接口才能生成代理类;CgLib Proxy不需要目标类有接口就能代理实现。

参考文献

Java三种代理模式:静态代理、动态代理和cglib代理:https://segmentfault.com/a/1190000011291179


目录
打赏
0
0
0
0
223
分享
相关文章
日志服务(SLS)集成 Spark 流计算实战
日志服务集成 Spark 流式计算:使用Spark Streaming和Structured Streaming对采集到日志服务中的数据进行消费,计算并将结果写回到日志服务。
8512 0
日志服务(SLS)集成 Spark 流计算实战
Linus 本尊也来了!为什么 KubeCon 越来越火了?
2015 年 11 月,第一届 KubeCon 在美国旧金山开始的时候,还只是个 200 人的小会议,2019 年的 7 月,KubeCon 第二次在中国举办,就有 3500 多位云原生、开源领域工程师齐聚一堂。
3310 0
如何配置 OpenAI 环境变量
如何配置 OpenAI 环境变量
363 0
GIS空间分析 栅格数据分析1 欧氏距离分析
本文讲述ArcGIS栅格数据欧氏距离分析、栅格数据重分类、栅格叠置分析等空间分析功能;
347 1
故障排除:Windows DVD Maker 无法刻录 DVD
Windows DVD Maker刻录失败可能由系统不兼容、软件版本过旧、驱动问题或磁盘格式引起。检查系统要求,确保至少有1.6 GHz处理器、512 MB RAM和4.7 GB硬盘空间。更新软件和驱动,尤其是DVD驱动及显卡驱动。调整刻录速度,确保使用兼容的DVD-R格式,并清洁刻录机。格式化磁盘至DVD-R格式也可解决问题。通过这些步骤可优化软件性能并解决刻录问题。
284 0
运筹优化学习04:Lingo的sum函数和for函数的使用方法介绍
运筹优化学习04:Lingo的sum函数和for函数的使用方法介绍
运筹优化学习04:Lingo的sum函数和for函数的使用方法介绍
性能最高提升50%,ECS倚天实例深度学习推理性能实测
本次实测涵盖图像分类识别、图像目标检测、自然语言处理以及搜索推荐等四种常见的深度学习推理场景
性能最高提升50%,ECS倚天实例深度学习推理性能实测
CSS进阶-CSS动画关键帧
【6月更文挑战第15天】CSS的`@keyframes`创建细腻动画,定义样式变化阶段以增强网页互动性。通过`animation`属性应用动画,如`fadeIn`示例。常见问题包括动画结束状态、卡顿和浏览器兼容性,解决办法涉及优化关键帧、使用硬件加速和添加前缀。进阶技巧包括多步骤动画和控制播放状态。例如,背景色渐变动画展示了颜色随时间变化的效果。学习和实践关键帧动画,提升Web开发技能。
359 7
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等