• Java反射技术


    反射机制

            Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,这种动态获取状态信息以及调用对象方法的功能称为Java语言的反射机制。简单来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,就可以通过反射机制来获得类的所有信息。

    基本的反射技术

    Class类

    在反射中只要我们获取了一个类的Class对象,我们就可以获取该类的所有信息,在Java中获取Class对象的方法有三种:

    1.对象名.getClass();  通过实例化对象的getClass()方法进行获取。

    1. String str = new String();
    2. Class cls = str.getClass();

    2.类名.class; 用过类名的class方法进行获取

    Class cls = String.class;

    3.Class.forName();通过Class的forName()方法进行获取,参数为类的完全限定名

    Class cls = Class.forName("java.lang.String");

    调用构造方法

    为了能够任意调用类的构造方法,Java的反射API提供了Construcor对象,该对象包含了一个构造方法的所有信息,但在调用构造方法之前,我们首先得获取该类的构造方法,部分实现代码如下:

    1. public class Main {
    2. public static void main(String[] args) throws Exception {
    3. //获取String类的Class对象
    4. Class cls = Class.forName("java.lang.String");
    5. // 获取构造方法String(String):
    6. Constructor cons = cls.getConstructor(String.class);
    7. // 调用构造方法:
    8. String str = (String) cons.newInstance("hello world");
    9. System.out.println(str);
    10. }
    11. }

    获取继承关系

    当我们获取到某个Class对象时,那么我们就可以通过下列方法获取该类的继承关系,部分实现代码如下:

    1. Class cls = Class.forName("java.lang.String");//获取String类的Class对象
    2. Class superClass = cls.getSuperclass();//获取该类父类类型
    3. Class[] interfaces = cls.getInterfaces();//获取该类的所有接口

    访问字段

    对于一个类中的字段,我们不仅可以通过Class对象获取该字段值,还可以对字段值进行修改,部分实现代码如下:

    1. import java.lang.reflect.Field;
    2. public class Main {
    3. public static void main(String[] args) throws Exception {
    4. //通过Person类中的get方法获取字段值
    5. Person person = new Person("Xiao Ming");
    6. System.out.println(person.getName()); // "Xiao Ming"
    7. //通过反射获取字段值
    8. Class cls = p.getClass();
    9. Field filed = cls.getDeclaredField("name");
    10. //由于name字段被private修饰,因此需要通过setAccessible(true)将name字段设置为允许访问
    11. filed.setAccessible(true);
    12. filed.set(person, "Xiao Hong");
    13. System.out.println(person.getName()); // "Xiao Hong"
    14. }
    15. }
    16. class Person {
    17. private String name;
    18. public Person(String name) {
    19. this.name = name;
    20. }
    21. public String getName() {
    22. return this.name;
    23. }
    24. }

    调用方法

    当我们获取到某个Class对象时,那么我们就可以通过下列方法实现方法的调用,部分实现代码如下:

    1. public class Main {
    2. public static void main(String[] args) throws Exception {
    3. // String对象:
    4. String s = "Hello world";
    5. // 获取String substring(int)方法,参数为int:
    6. Method m = String.class.getMethod("substring", int.class);
    7. // 在s对象上调用该方法并获取结果:
    8. String r = (String) m.invoke(s, 6);
    9. // 打印调用结果:
    10. System.out.println(r);
    11. }
    12. }

    反射的功能

    在运行期构造一个类的对象;

    获取方法、属性等类中的基本信息;

    调用类对象的方法;生成动态代理。

    动态代理

    动态代理是代理模式的一种实现方式,代理模式除了动态代理还有 静态代理,只不过静态代理能够在编译时期确定类的执行对象,而动态代理只有在运行时才能够确定执行对象是谁。代理可以看作是对最终调用目标的一个封装,我们能够通过操作代理对象来调用目标类,这样就可以实现调用者和目标对象的解耦合。

    代理模式所涉及的角色有三个:
    (1)、抽象主题角色(Subject):声明了真实主题和代理主题的公共接口,这样一来在使用真实主题的任何地方都可以使用代理主题。
    (2)、代理主题角色(Proxy):代理主题角色内部含有对真实主题的引用,从而可以操作真实主题对象;代理主题角色负责在需要的时候创建真实主题对象;代理角色通常在将客户端调用传递到真实主题之前或之后,都要执行一些其他的操作,而不是单纯地将调用传递给真实主题对象。
    (3)、真实主题角色(RealSubject):定义了代理角色所代表的真实对象。
    附:在WCF或者WebService的开发过程中,我们在客户端添加服务引用的时候,在客户程序中会添加一些额外的类,在客户端生成的类扮演着代理主题角色,我们客户端也是直接调用这些代理角色来访问远程服务提供的操作。这个是远程代理的一个典型例子。

    动态代理在mybatis中的应用

    在项目中配置Mybatis时,我们仅创建了映射器接口映射文件,并未创建映射器接口的实现类,但当我们使用Sqlsesion的getMapper()方法时,Mybatis却自动帮我们实现了映射器接口的实现类,从而可以使用映射器接口中的方法。

  • 相关阅读:
    mac跑分工具Geekbench v6.2.1
    LabVIEW使用源代码控制
    2520. 统计能整除数字的位数
    Kylin ext3/4 xfs手动扩容根分区
    Java实战项目之图书借阅管理系统【源码+课后指导】
    公园【百度之星】/图论+dijkstra
    Java Double toString()方法具有什么功能呢?
    屋顶太阳能光伏系统的性能分析指标研究
    【MySQL事务篇】多版本并发控制(MVCC)
    蓝桥杯必备算法分享——差分算法
  • 原文地址:https://blog.csdn.net/qq_51956240/article/details/126289125