反射基础:
package reflection; /** * Created by : Infaraway * DATE : 2017/3/2 * Time : 23:06 * Funtion : Person为父类 */ public class Person { public String name; public Integer age; private String address; private String phoneNumber; private String email; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } private void personMethod(){ System.out.println("this is personMethod..."); } public String getName() { return name; } public void setName(String name) { this.name = name; } public void setName(String name, Integer age){ this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
package reflection; /** * Created by : Infaraway * DATE : 2017/3/3 * Time : 12:17 * Funtion : Student子类 */ public class Student extends Person { public String classes; private String school; private String grade; public Student() { } public Student(String name, Integer age) { super(name, age); } private void studentMethod(String school){ System.out.println("this is studentMethod..."); } }
最基本的反射使用为一下的代码表示:主要获取 字段 和 方法为主;
package reflection; import org.junit.Test; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * Created by : Infaraway * DATE : 2017/3/2 * Time : 23:10 * Funtion : 反射及基本用法 */ public class testReflect { String className = "reflection.Student"; /** * 测试反射的基本用法 * @throws Exception */ @Test public void testPerson() throws Exception { Class clazz = Class.forName("reflection.Person"); // 1. Class类中的getFields,getMethods,getConstructors方法 // 分别返回提供的 public 域 方法 和构造器 // 并且包括超类的公有成员 Field[] fields = clazz.getFields(); for (Field field : fields) { System.out.println(field.getName()); } Method [] methods = clazz.getMethods(); for (Method method: methods) { System.out.println(method.getName()); } Constructor [] constructors = clazz.getConstructors(); for (Constructor constructor : constructors) { System.out.println(constructor.getName()); } // 2. Class类中的getDeclaredFields,getDeclaredMethods,getDeclaredConstructors方法 // 获取所有的方法包括 private方法,且只获取当前类声明的方法 // 不包括超类的成员 Field[] fieldsDeclared = clazz.getDeclaredFields(); for (Field field : fieldsDeclared) { System.out.println(field.getName()); } Method [] methodsDeclared = clazz.getDeclaredMethods(); for (Method method: methodsDeclared) { System.out.println("method2---"+method.getName()); } Constructor [] constructorsDeclared = clazz.getDeclaredConstructors(); for (Constructor constructor : constructorsDeclared) { System.out.println(constructor.getName()); } // 3.获取指定的方法 getDeclaredMethod可以获取私有的方法 // 获取特定方法时,需要两个东西确定调用的方法:1)方法名,2)方法的参数(重载) Method methodSp = clazz.getDeclaredMethod("setName",String.class); System.out.println(methodSp); //当需要使用反射式,参数类型必须是包装类 int --> Integer 等等 Method methodSp2 = clazz.getDeclaredMethod("setName",String.class, Integer.class); System.out.println(methodSp2); //4. 执行方法 Object object = clazz.newInstance(); methodSp.invoke(object, "zhong"); } }
也可以通过反射获取并且调用父类的方法(包括public 和private)
以下只提供实现上述方法的工具类:
package reflection; import java.lang.reflect.Method; /** * Created by : Infaraway * DATE : 2017/3/3 * Time : 12:18 * Funtion : */ public class ReflectUtils { /** * 返回方法 * @param clazz 类 * @param methodName 方法名称 * @param args 参数列表 * @return 返回方法(由于使用了setAccessible方法,改使private的 method也可执行) */ public static Method getMethod(Class clazz, String methodName, Object...args) { Method method = null; Class [] parametersTypes = new Class[args.length]; //得到所有参数的class for (int i = 0; i < args.length; i++) { parametersTypes[i] = args[i].getClass(); } for (;clazz != Object.class; clazz = clazz.getSuperclass()){ try { method = clazz.getDeclaredMethod(methodName,parametersTypes); method.setAccessible(true); return method; } catch (NoSuchMethodException e) { e.printStackTrace(); } } return null; } /** * 获取clazz中的methodName方法,该方法可能是私有方法,也可能是父类中的私有方法 * @param clazz 类 * @param methodName 方法名称 * @param parametersTypes 参数类型数组 * @return 方法的对象 */ public static Method getSuperMehtod(Class clazz, String methodName, Class...parametersTypes){ Method method = null; for (;clazz != Object.class; clazz = clazz.getSuperclass()){ try { method = clazz.getDeclaredMethod(methodName, parametersTypes); return method; }catch (Exception e){ //method不在当前类定义,继续向上转型 } } return null; } /** * 反射执行调用方法,可以使public 或者 private 可以使当前类或者 父类 * @param obj 类对象 * @param methodName 方法名 * @param args 参数列表 * @return 方法的返回值 */ public static Object invokeMethod(Object obj, String methodName, Object...args){ Class [] parametersTypes = new Class[args.length]; //得到所有参数的class for (int i = 0; i < args.length; i++) { parametersTypes[i] = args[i].getClass(); } try { Method method = getSuperMehtod(obj.getClass(), methodName, parametersTypes); //设置私有方法可调用 method.setAccessible(true); //执行method方法 并返回方法的返回值 return method.invoke(obj, args); }catch (Exception e ){ e.printStackTrace(); } return null; } }
本文所需完整版代码:https://git.oschina.net/infaraway/basisJava/tree/master/src/reflection