java反射详解和动态代理

最近闲来无事,刚好看到以前的java反射笔记,这里整理一下,有不足之处还望指出;

  在学习java反射机制之前,我们先提出这么一个问题:在Java中,能不能在运行时针对一个Java类,获取它的属性和方法呢?

  答案是肯定的,java中解决这个问题就是使用的我们今天需要讲的java反射机制。

  • 1.什么是java反射?

  java提供一种在运行时动态的获取class的方法和属性以及参数的机制,这种机制就是反射机制。换言之,java可以加载一个在运行时才得知名称的class,并获得它的详细结构(包括权限,继承类等等)。

在JDK中提供API来实现这种机制,API就是reflection APIs。在下文我们将详细了解reflection APIs 。

  • 2.Reflection API详解

  java内部是怎么实现这种机制的呢?让我们来详细看看Reflection API。java反射相关的API都在java.lang.reflect包中。结构图如下:

  member接口:用于获取类的构造方法,字段和成员方法。

  

  AccessibleObject 类:是 Field、Method 和 Constructor 对象的基类。它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。(通俗解释一下就是获得了更高的使用权限);

  

  Array 类:提供了动态创建和访问 Java 数组的方法。

  Constructor类:提供关于类的单个构造方法的信息以及对它的访问权限

  Field:提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。

  Modifier:类提供了 static 方法和常量,对类和成员访问修饰符进行解码。

  Proxy:提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。

  • 3.Java反射机制提供了什么功能?

  java反射机制提供了以下功能:

    在运行时判断任意一个对象所属的类;

    在运行时构造任意一个类的对象;

    在运行时判断任意一个类所具有的方法和变量;

    在运行时调用任意一个对象的方法;

    在运行时创建新类对象;

  • 4.java反射机制的实现路程

  在java反射机制中,使用反射功能的时候必须先获取类的class对象,再通过class对象获取其他对象(这里的其他对象就是方法对象等)。

  那么如何获取类的class对象呢?

  1.调用getclass

  2.运用.class语法

  3.利用静态方法class.forName("类的全类名")

  4.使用原始包装类的TYPE语法

这里需要注意的是:这里返回的原始类型,和.class等返回的不一样;

在获取了类的class对象之后,就可以获取类的其他结构。。。

  1、获取类的fields对象

java 的 Class<T>类提供了几个方法获取类的属性

  通过测试可以看出区别:

可见:

getFields返回的是声明为public的属性(包括父类的属性);

getDeclaredFields返回的是指定类的所有属性(不包括父类的属性);

  2、获取类的method对象

java的Class<T>提供如下几个方法获取类的成员方法

 

注意:区别和获取属性方法的区别相同。

  3、获取类的constructor对象

  通过反射机制获取指定类的构造器,然后调用这个构造器去创建该类的一个实例

java的Class<T>类提供了几个方法获取类的构造器

  新建类的实例

通过反射机制调用类的构造器区创建类的实例,有如下几种方法:

注意:这里就可以看出我们通常所说的类的实例对象,和类的class对象不是同一个概念(通俗解释就是类的class可以生出多个类的实例对象(个人观点,方便理解而已))。

 4、调用类的函数

这里调用的才是类的方法,class类调用的是指定类的函数对象(method对象)

如何调用呢?调用方法当然是通过方法对象。

  通过Method对象调用它的invoke()实现

invoke(Object obj, Object... args) 
          对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。

这里一定要注意如果调用的方法是private修饰的,那么必须设置Accessible为true;这里的setAccessible()方法Method父类AccessibleObject的方法。

 5、获取和设置类的属性值

class类获取指定类的Filed对象,通过Filed对象调用方法去设置和获取属性值;

  • 5.动态创建代理类

  在这之前我们先简单说一下代理模式,代理模式就是为其他对象提供一种代理,用以控制对这个对象的访问,这种模式在spring中的AOP中应用广泛;

代理模式的详细解释这里就不赘述了,各位可以去翻阅相关资料。

接下来我们详细看看这个动态代理

这个InvocationHandler类是代理实例的调用处理程序实现的接口。

每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。

动态Proxy是这样的一种类:

  它是在运行时生成的类(这一点一定要注意),在生成时你必须提供一组接口(interface)给它,然后该class就宣称它实现了这组interface。你可以把这个class的实例当做这些interface中的任何一个来使用。当然这个Dynamic Proxy其实就是一个Proxy(代理类),它并不会为你实现实质性的功能,在使用Proxy的时候必须为它实现invacationHandler接口(这个接口的实现类才会帮我们做具体的工作)。

举例理解Dynamic Proxy

 

 至此java反射机制大概讲解完毕,文中不足希望指出,共同进步。

  

  

猜你喜欢

转载自www.cnblogs.com/yizhixiaoxiaoyu/p/10932402.html
今日推荐