Java 反射

Java 反射和动态代理

反射与动态代理原理

1 关于反射
反射最大的作用之一就在于我们可以不在编译时知道某个对象的类型,而在运行时通过提供完整的”包名+类名.class”得到。注意:不是在编译时,而是在运行时。

功能:
•在运行时能判断任意一个对象所属的类。
•在运行时能构造任意一个类的对象。
•在运行时判断任意一个类所具有的成员变量和方法。
•在运行时调用任意一个对象的方法。
说大白话就是,利用Java反射机制我们可以加载一个运行时才得知名称的class,获悉其构造方法,并生成其对象实体,能对其fields设值并唤起其methods。

应用场景:
反射技术常用在各类通用框架开发中。因为为了保证框架的通用性,需要根据配置文件加载不同的对象或类,并调用不同的方法,这个时候就会用到反射——运行时动态加载需要加载的对象。

特点:
由于反射会额外消耗一定的系统资源,因此如果不需要动态地创建一个对象,那么就不需要用反射。另外,反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。

2 动态代理
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在两者之间起到中介的作用(可类比房屋中介,房东委托中介销售房屋、签订合同等)。
所谓动态代理,就是实现阶段不用关心代理谁,而是在运行阶段才指定代理哪个一个对象(不确定性)。如果是自己写代理类的方式就是静态代理(确定性)。

组成要素:
(动态)代理模式主要涉及三个要素:
其一:抽象类接口
其二:被代理类(具体实现抽象接口的类)
其三:动态代理类:实际调用被代理类的方法和属性的类

实现方式:
实现动态代理的方式很多,比如 JDK 自身提供的动态代理,就是主要利用了反射机制。还有其他的实现方式,比如利用字节码操作机制,类似 ASM、CGLIB(基于 ASM)、Javassist 等。
举例,常可采用的JDK提供的动态代理接口InvocationHandler来实现动态代理类。其中invoke方法是该接口定义必须实现的,它完成对真实方法的调用。通过InvocationHandler接口,所有方法都由该Handler来进行处理,即所有被代理的方法都由InvocationHandler接管实际的处理任务。此外,我们常可以在invoke方法实现中增加自定义的逻辑实现,实现对被代理类的业务逻辑无侵入。

Java反射

利用反射的优点:

在编写程序时,如果知道想要查看的field(类的域成员)名和类型,查看指定的域是一件简单的事情

而利用反射机制可以查看在编译时还不清楚的对象域。

Class类的

  1. getFields()
  2. getMethods()
  3. getConstructors()

方法,分别返回类提供的public的域,方法和构造器 -> 数组,(包括超类的公有成员)

Class类的

  1. getDeclareFields()
  2. getDeclareMethods()
  3. getDeclareConstructors()

方法,分别返回类中声明的全部域,方法和构造器,包括私有和受保护的,(不包括超类的成员)

modifier -> 有修饰词的意思,如:public,private,static…都是修饰词

java.lang.reflect包中有Field,Method,Constructor三个类,用于描述类的域,方法,构造器

三个类都有一个getModifiers()的方法,返回一个整型,描述修饰词的,如public的

反射机制的默认行为,受限于Java的访问控制

如果一个Java程序没有收到安全管理器的控制,就可以覆盖访问控制

Field,Method,Constructor对象的setAccessible(),例如:

f.setAccessible(true);// 修改f(Field对象)的访问权限

写一个利用反射分析类中fields,methods,constructor的小程序/脚本

  • 即查看对象的数据域名称和类型
  • 获得对应Class对象

写一个利用反射分析对象的脚本

Java动态代理

问题:动态代理是解决什么问题的?

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2022-2023 ligongzhao
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信