本文主要解释一下几个问题
1、如何根据对象获得类的所有方法和属性
2、如何根据类名获得类的方法和属性
3、如何选择被反射类的构造函数 并 调用该函数获得实例
4、如何批量执行无参函数
5、如何调用指定名字的方法
6、如何调用有参的函数
7、如何反射调用类的私有方法
————————————————————————————————————
package com.hhf.reflect; /** * 等待被反射的类 * 用于解释如何通过反射获得类的方法与属性 * 如何选择被反射类的构造函数 * 如何批量执行类的函数 * @author HHF * 2014年4月17日 */ public class DataFunc { private int data1; private int data2; private int result; public DataFunc() { data1=0; data2=0; result=0; } public DataFunc(int x,int y){ data1=x; data2=y; } public int add(){ result=data1+data2+1; return result; } public int substract(){ result=data1-data2; return result; } public int multiply(){ result=data1*data2; return result; } public int divide(){ result=data1/data2; return result; } }
package com.hhf.reflect; /** * 等待被反射的类 * 主要为了解释一个有参的方法如何反射调用 * @author HHF * 2014年4月17日 */ public class DataFunc2 { @SuppressWarnings("unused") private int data1; @SuppressWarnings("unused") private int data2; private int result; public DataFunc2() { data1 = 0; data2 = 0; result = 0; } public DataFunc2(int x, int y) { data1 = x; data2 = y; } public int add2(int a, int b, int c) { result = a + b + c; return result; } }
package com.hhf.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Refect { // JAVA反射机制是在 运行状态 中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 // Java反射机制主要提供了以下功能: // 在运行时判断任意一个对象所属的类; // 在运行时构造任意一个类的对象; // 在运行时判断任意一个类所具有的成员变量和方法; // 在运行时调用任意一个对象的方法;生成动态代理。 // 使用反射机制的步骤: // 导入java.lang.relfect 包 // 遵循三个步骤 // 第一步是获得你想操作的类的 java.lang.Class 对象 // 第二步是调用诸如 getDeclaredMethods 的方法 // 第三步使用 反射API 来操作这些信息 public static void main(String [] args){ Refect refect = new Refect(); System.out.println("-----------------------通过对象获得方法和属性------------------------"); refect.reflectInstance(); System.out.println("-----------------------通过类名获得方法与参数----------------------------"); refect.reflectClass(); System.out.println("-----------------------批量执行方法------------------------------"); refect.RunMethod(); System.out.println("-----------------------调用指定无参方法----------------------------"); refect.RunSepcMethod(); System.out.println("-----------------------调用有参数方法------------------------------"); refect.RunParmMethod(); } /** * 通过对象获得类的 方法和属性 */ public void reflectInstance() { try { DataFunc a = new DataFunc(); Class cla = Class.forName(a.getClass().getName());// 根据类的全路径进行类加载,返回该类的Class对象 Method[] method = cla.getDeclaredMethods();// 利用得到的Class对象的自审,返回方法对象集合 System.out.println("********该类的所有方法********"); for (Method me : method) {// 遍历该类方法的集合 System.out.println(me.toString());// 打印方法信息 } System.out.println("********该类的所有属性********"); Field[] field = cla.getDeclaredFields();// 利用得到的Class对象的自审,返回属性对象集合 for (Field me : field) { // 遍历该类属性的集合 System.out.println(me.toString());// 打印属性信息 } } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * 通过类的完整路径获得类的 方法和属性 */ public void reflectClass() { try { Class cla = Class.forName("com.hhf.reflect.DataFunc");// 根据类的全路径进行类加载,返回该类的Class对象 Method[] method = cla.getDeclaredMethods();// 利用得到的Class对象的自审,返回方法对象集合 System.out.println("********该类的所有方法********"); for (Method me : method) {// 遍历该类方法的集合 System.out.println(me.toString());// 打印方法信息 } System.out.println("********该类的所有属性********"); Field[] field = cla.getDeclaredFields();// 利用得到的Class对象的自审,返回属性对象集合 for (Field me : field) { // 遍历该类属性的集合 System.out.println(me.toString());// 打印属性信息 } } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * 指定构造函数 * 可以另外的通过构造函数给函数属性传递参数 并调用方法 */ public void RunMethod() { try { // 获得指定字符串类对象 Class cla = Class.forName("com.hhf.reflect.DataFunc"); // 设置Class对象数组,用于指定构造方法类型 Class[] cl = new Class[] { int.class, int.class }; // 获得Constructor构造器对象。并指定构造方法类型 Constructor con = cla.getConstructor(cl); // 给传入参数赋初值 Object[] x = { new Integer(33), new Integer(67) }; // 得到实例 Object obj = con.newInstance(x); Method[] method = cla.getDeclaredMethods();// 利用得到的Class对象的自审,返回方法对象集合 //批量调用方法(无参数的方法) for (Method me : method) {// 遍历该类方法的集合 System.out.print("调用方法:"+me.toString());// 打印方法信息 String str = me.invoke(obj).toString(); System.out.println("\t该方法执行结果"+str); } } catch (Exception e) { e.printStackTrace(); } } /** * 指定方法名的调用方法 */ public void RunSepcMethod() { try { // 获得指定字符串类对象 Class cla = Class.forName("com.hhf.reflect.DataFunc"); // 设置Class对象数组,用于指定构造方法类型 Class[] cl = new Class[] { int.class, int.class }; // 获得Constructor构造器对象。并指定构造方法类型 Constructor con = cla.getConstructor(cl); // 给传入参数赋初值 Object[] x = { new Integer(33), new Integer(67) }; // 得到实例 Object obj = con.newInstance(x); Method specMethod = cla.getMethod("add"); String str = specMethod.invoke(obj).toString(); System.out.println("调用方法"+specMethod.getName()+"的结果\t"+str); } catch (Exception e) { e.printStackTrace(); } } /** * 调用有参数的方法 */ public void RunParmMethod() { try { // 获得指定字符串类对象 Class cla = Class.forName("com.hhf.reflect.DataFunc2"); // 设置Class对象数组,用于指定构造方法类型 Class[] cl = new Class[] { int.class, int.class }; // 获得Constructor构造器对象。并指定构造方法类型 Constructor con = cla.getConstructor(cl); // 给传入参数赋初值 Object[] x = { new Integer(33), new Integer(67) }; // 得到实例 Object obj = con.newInstance(x); // Method specMethod1 = cla.getMethod("a", int.class, int.class); Class[] c2 = new Class[] { int.class, int.class, int.class}; Method parmMethod = cla.getMethod("add2", c2); // 给传入参数赋初值 Object[] x2 = { new Integer(3), new Integer(6), new Integer(1)}; // 得到实例 String str = parmMethod.invoke(obj, x2).toString(); System.out.println("调用方法"+parmMethod.getName()+"的结果\t"+str); } catch (Exception e) { e.printStackTrace(); } } }
//等待被反射的类 其中只有一个私有方法 public class PrivateMethod { //私有方法 private int add(int a, int b){ return a +b+1 ; } }
//反射调用私有方法 //获取目标类的class对象 Class<PrivateMethod> class1 = PrivateMethod.class; //获取目标类的实例 Object instance = class1.newInstance(); //getDeclaredMethod() 可获取 公共、保护、默认(包)访问和私有方法,但不包括继承的方法。 Method method = class1.getDeclaredMethod("add", new Class[]{int.class,int.class}); //值为true时 反射的对象在使用时 应让一切已有的访问权限取消 method.setAccessible(true); Object result = method.invoke(instance, new Object[]{1,2});