Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。当然反射本身并不是一个新概念,它可能会使我们联想到光学中的反射概念,尽管计算机科学赋予了反射概念新的含义,但是,从现象上来说,它们确实有某些相通之处,这些有助于我们的理解。
Java反射机制主要提供下面几种用途:
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的方法
首先看一个简单的例子,通过这个例子来理解Java的反射机制是如何工作的。
View Code
当传入的参数是java.lang.String时,会输出如下结果
View Code
这样就列出了java.lang.String类的所有方法名、及其限制符、返回类型及抛出的异常。这个程序使用Class类forName方法载入指定的类,然后调用getMethods方法返回指定类的方法列表。java.lang.reflect.Method用来表述某个类中的单一方法。
使用java的反射机制,一般需要遵循三步:
获得你想操作类的Class对象
通过第一步获得的Class对象去取得操作类的方法或是属性名
操作第二步取得的方法或是属性
Java运行的时候,某个类无论生成多少个对象,他们都会对应同一个Class对象,它表示正在运行程序中的类和接口。如何取得操作类的Class对象,常用的有三种方式:
调用Class的静态方法forName,如上例;
使用类的.class语法,如:Class cls = String.class;
调用对象的getClass方法,如:String str = “abc”;Class cls = str .getClass();
下面将通过实例讲述如何通过前面所诉的三步来执行某对象的某个方法:
View Code
前面说过,Java程序的每个类都会有个Class对象与之对应。Java反射的第一步就是获得这个Class对象,如代码14行。当然,每个类的方法也必有一个Method对象与之对应。要通过反射的方式调用这个方法,就要首先获得这个方法的Method对象,如代码16行,然后用Method对象反过来调用这个方法,如代码18行。注意16行getMethod方法的第一个参数是方法名,第二个是此方法的参数类型,如果是多个参数,接着添加参数就可以了,因为getMethod是可变参数方法。执行18行代码的invoke方法,其实也就是执行show方法,注意invoke的第一个参数,是DisPlay类的一个对象,也就是调用DisPlay类哪个对象的show方法,第二个参数是给show方法传递的参数。类型和个数一定要与16行的getMethod方法一直。
上例讲述了如何通过反射调用某个类的方法,下面将再通过一个实例讲述如何通过反射给某个类的属性赋值:
View Code
Java的发射机制中类有Class对应,类的方法有Method对应,当然属性也有Field与之对应。代码中注释已经做了详细的注释,在此不再赘述。但要注意,Field提供了get和set方法获取和设置属性的值,但是由于属性是私有类型,所以需要设置属性的可访问性为true,如代码50~51行。也可以在为整个fields设置可访问性,在40行下面使用AccessibleObject的静态方法setAccessible,如:AccessibleObject.setAccessible(fromFields, true);
前面讲述了如何用Java反射机制操作一个类的方法和属性,下面再通过一个实例讲述如何在运行时创建类的一个对象:
View Code
此例和上例运行的结果是相同的。但是copyBean方法返回的对象不再是外面传入的,而是由方法内部产生的,如第40行代码所示。注意:Class的newInstance方法,只能创建只包含无参数的构造函数的类,如果某类只有带参数的构造函数,那么就要使用另外一种方式:fromClass.getDeclaredConstructor(int.class,String.class).newInstance(24,“wanggc”);
至此,Java反射机制的常用机能(运行时调用对象的方法、类属性的使用、创类类的对象)已经介绍完了。
补充:在获得类的方法、属性、构造函数时,会有getXXX和getgetDeclaredXXX两种对应的方法。之间的区别在于前者返回的是访问权限为public的方法和属性,包括父类中的;但后者返回的是所有访问权限的方法和属性,不包括父类的。
给大家来推荐一些Linux的相关的学习资料,可以加裙:1091181875
java-环境搭建及基础语法
构造函数/继承
综合实战
Java 反射机制浅析
最新推荐文章于 2021-02-16 12:52:39 发布