利用反射机制,获取类的字段、方法、并实现简单调用

来源:互联网 发布:python 字典 list 编辑:程序博客网 时间:2024/04/29 09:58


这篇文章是为之后要介绍Android的ICO框架做预备的,所以,如果想最近学习Android的ICO框架的同学,可以稍微看一下。

首先,简单介绍一下Java里面的反射。

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制

不知道这样的一段解释,你能否看懂。如果更简单的说,反射就是能够根据你给出类名实例化出一个实实在在的对象。所以,对象的实例化就不是写死的了,我们可以根据传入的类名不同,从而可以实例化出不同的对象。这种方式可以和工厂设计模式很好的结合,从而可以更加灵活的创建对象。

下面,我们简单的介绍一下如何使用反射来进行对象的创,以及方法、字段的获取与使用。

首先,给出要用的实体类的代码,重点注意一下字段和方法的权限的修饰符

package edu.qust.demo;/** *  * @ClassName: Person * @Description: Person实体类 * @author: ZhaoKaiQiang * @time: 2014-7-18上午10:41:23 * @version: V1.0 */public class Person {private int age;private String name;protected int height;public String school;Person(){this.name = "Person";age = 22;}Person(String name) {this.name = name;}private String showName(String _name) {return "My name is " + _name;}public void setAge(int age) {this.age = age;}public int getAge() {return age;}@Overridepublic String toString() {return "My name is " + name + ", i'm " + age + " years old";}}

下面,我们开始介绍,在Java中,如何使用代码实现反射。

下面是测试程序

package edu.qust.demo;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class Main {private static Person person;private static Class<Person> cls;@SuppressWarnings("unchecked")public static void main(String[] args) {person = new Person("Zhao");cls = (Class<Person>) person.getClass();creatClassByReflection();printAllMethods();printAllFileds();invokePrivateMothod();}/** * 利用反射创建对象 */private static void creatClassByReflection() {try {Person accpTeacher = (Person) Class.forName("edu.qust.demo.Person").newInstance();System.out.println(accpTeacher.toString());System.out.println();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}}/** * 获取并调用私有方法 */private static void invokePrivateMothod() {try {// 获取方法名为showName,参数为String类型的方法Method method = cls.getDeclaredMethod("showName", String.class);// 若调用私有方法,必须抑制java对权限的检查method.setAccessible(true);// 使用invoke调用方法,并且获取方法的返回值,需要传入一个方法所在类的对象,new Object[]// {"Kai"}是需要传入的参数,与上面的String.class相对应String string = (String) method.invoke(person,new Object[] { "Kai" });System.out.println(string);} catch (NoSuchMethodException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}/** * 获取并打印所有的字段名 */private static void printAllFileds() {Field[] field = cls.getDeclaredFields();System.out.println("getFields():获取所有权限修饰符修饰的字段");for (Field f : field) {System.out.println("Field Name = " + f.getName());}System.out.println();}/** * 获取并打印所有的方法名 */private static void printAllMethods() {Method[] method = cls.getDeclaredMethods();System.out.println("getDeclaredMethods():获取所有的权限修饰符修饰的Method");for (Method m : method) {System.out.println("Method Name = " + m.getName());}System.out.println();}}

下面是上面的测试程序的输出结果

My name is Person, i'm 22 years oldgetDeclaredMethods():获取所有的权限修饰符修饰的MethodMethod Name = toStringMethod Name = showNameMethod Name = setAgeMethod Name = getAgegetFields():获取所有权限修饰符修饰的字段Field Name = ageField Name = nameField Name = heightField Name = schoolMy name is Kai

在java.lang.reflect包中,提供了类和接口,来获得关于类和对象的反射信息。


在这里,我们目前只关注Field和Method这两个类,分别代表类的成员变量和方法。

除此之外,在java.lang.Class,还有个反射需要用到的很重要的类,Class,这个类中封装了一个类所有的信息,包括各种全县修饰符修饰的成员变量和方法,因此,我们可以用这个类,来获取类的各种信息。Class继承自Object,利用Object.getClass可以获取到某对象运行时类的 Class 对象。

我们的操作,主要就是获取某个类的Class对象,然后利用这个对象,就可以获取到某个类所有的成员变量以及方法,并且可以对任意权限修饰符修饰的方法进行调用,注意,是任意哦,即使是private修饰的类的方法,我们也可以利用反射进行调用,所以说反射可以说是相当逆天啊。

首先看第一个方法的输出

My name is Person, i'm 22 years old

在这里,我们利用一个类的String字符串的名字,实例化出了一个对象,这就是上面所说的,根据传入的字符串的不同,可以创建出不同的对象。调用newInstance方法,Java会去找默认的构造函数,完成对象的初始化,因此得到了这样的结果。

再看第二个方法的输出

getDeclaredMethods():获取所有的权限修饰符修饰的Method
Method Name = toString
Method Name = showName
Method Name = setAge
Method Name = getAge

我们使用getDeclaredMethods这个方法,获取到了类里面所有的方法,然后我们进行遍历,将类名进行简单的输出。

第三个方法的结果和第二个差不多,只不过就是把Method换成了Filed,然后把字段名进行了输出。

getFields():获取所有权限修饰符修饰的字段

Field Name = age

Field Name = name

Field Name = height

Field Name = school

第四个方法中,我们根据方法名,获取到具体某一个方法,然后传入参数,利用invoke进行方法的调用。再调用之前,必须设置method.setAccessible(true);从而可以调用使用private修饰的方法。

除了上面代码中,用到的这些方法,Class类还有很多其他的方法。更多具体的使用,还是看文档去吧!

0 0