摘要:在Java开发中,反射的应用尤其的广泛,很多优秀的框架都会充分利用Java的反射来对程序进行解耦,包括很多的设计模式也充分利用了反射的机制。反射的应用还包括了动态地改变数组长度和swing中用户表单的验证,学习好Java的反射对java的认识和各个框架的了解是很有帮助的。
一、反射机制
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
在正常情况下,需要先有一个类的完整路径引入之后才可以按照固定的格式产生实例化对象,但是在java中也允许通过一个实例化对象找到一个类的完整信息,这就是java的反射方式。
图1二、Class类
Class类是java反射的源头,Class本身表示一个类的本身,通过Class可以完整地得到一个类中的完整结构,包括类的方法定义,属性定义等。我们知道,在Java中所有的对象没有声明父类时,都默认继承Object类,getClass就是Object类中的方法,返回的就是Class类,这么看来java中的所有类的对象实际上都是Class类的实例,所有的对象都可以转变成Class类型表示。
2.1 实例化Class类
因为Class本身没有定义任何的构造方法,所以如果要使用它首先要通过forName()方法实例化对象。除了通过forName()方法实例化外还有“对象.getClass”和“类.class“方法实例化;如下图
图2 图32.2 Class类的常用方法
图42.3 通过Class获得构造函数
图5 图6之前关于Class的实例中我们采用forName()的方式,但是我们发现这种方式没有办法传递实例化参数。想要传实例化参数我们可以通过Constructo的newInstance方法,如下图;
图7
2.4 通过Class获得方法
我们可以通过class的getMethods()方法获得Method类的对象数组,想获得更多Method类的信息通过如下方法获得;
图8如上图我们通过Method的方法获得了方法的一些信息,这里要注意的是我们在获得访问修饰符时并不是直接获得public ,private等语意访问就是符,而是先获得Modifier的整数类型,再通过Modifier.toString(int mod)来获得语意上的修饰符。
我们还可通过Method来调用类中的任意方法,如下图
图10我们也可以调用带参数的方法,如下图
图112.5 通过Class获得属性
我们可以通过class的getDeclaredFields()和getFields()方法获得Field类的对象数组,getDeclaredFields()获取本类中单独定义的属性,getFields()获得继承来的属性。想获得更多Field类的信息通过如下方法获得;
图12 图13三、反射机制的深入应用
我们或许有这样的疑问,反射机制有什么用,我们不都是通过正常的方式来吗?实例化对象直接调用构造函数、方法和属性。。。但是有用过spring框架的朋友就会有这样的体会,我们把类配置到了bean容器中,我们可以通过配置bean容器来操作对象,这其实就是Java的反射机制来实现的,我们在运行时读取配置文件,通多反射机制调用其中的方法设置其中的属性。我们用的aop其实也是通过反射得以实现,aop的原型其实来源于动态代理,动态代理就是反射的最常见的应用。其实我们用的注解也是有反射的应用,这里我不做更深入的细说。
关于动态代理中应用的反射可以看看我前面关于Java动态代理的文章。下面我就举例说说反射机制在数组中的应用,如何动态地改变数组的长度,这个知识较为基础又很好地说明了反射对Java程序设计的意义。为什么说Java是动态的语言,就是因为反射机制的存在。
图14
网友评论