JavaEE使用到的所有开发框架里面到处都是反射的身影,没有反射就没有开发框架。下面主要结合简单Java类来进行反射开发的深入研究。
class Emp1{ private String name; private int age; private char gender; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public char getGender() { return gender; } public void setGender(char gender) { this.gender = gender; } public String toString() { return "Emp{" + "name=" + this.name + ", age=" + this.age +",gender="+ this.gender+'}'; } } public class Test{ public static void main(String[] args) { Emp1 emp1 = new Emp1(); emp1.setName(""); emp1.setAge(20); emp1.setGender('女'); System.out.println(emp1); } }
由上述代码可以看出在之前我们一直使用的是getter和setter方法对属性进行值的设置;对于较少类的情况下看不出什么,当我们存在多个类时,存在更多的私有变量时,我们还要对其一个一个进行setter是不是显得麻烦呢?
现在希望能对程序做简化,输入字符串 "属性名称:属性值|属性名称:属性值|属性名称:属性值|....",就可以将类中的属性设置好。希望通过此程序实现任意的简单Java类的属性设置。
现在所有的操作是通过Test类调用EmpAction类实现的,而EmpAction类的主要作用是在于定位要操作的属性类型。同时该程序应该符合于所有简单的Java类开发形式,因此对于我们的设计而言必须有一个单独的类 (BeanOperation)(实现此适配功能)
Emp类设计(简单Java类):
package reflect; //集体操作属性的类 public class Emp { private String name; private String job; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } public String toString() { return "Emp{" + "name=" + this.name + ", job=" + this.job +'}'; } }
BeanOperation类设计(公共程序类)
package reflect; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.KeyStore.Entry.Attribute; import java.security.Timestamp; //通过反射使得比较shi'yong //负责实现自动的VO匹配 public class BeanOperation { //无参构造方法,如果现在类中没有无参构造则在后期的实例化对象时无法使用Class类调用 private BeanOperation() {} //负责类中属性操作(按照 emp.name:lemon|emp.job:student 对属性进行赋值操作) public static void setBeanValue(Object actionObject, String msg) throws NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //对字符串进行拆分,实现内容的设置 //1.按照|进行拆分,可将已知字符串拆分成 类名.属性名:属性值的形式 String [] result = msg.split("\\|"); for(int i = 0;i < result.length;i++) { //2.按照 :进行拆分,可将已知字符串拆分成 : 类名.属性名 和 属性值 的形式 String[] temp = result[i].split(":"); //属性名 String attribute = temp[0]; //属性内容 String value = temp[1]; //3.对 类名.属性名按照 . 再进行拆分,拆分结果为: 类名 和 属性名 String[] fields = attribute.split("\\."); //调用当前操作的简单Java类对象 Object currentObject = getObject(actionObject,fields[0]); //调用简单Java类的setter方法 setObject(currentObject,fields[1],temp[1]); } } //负责调用getter方法取得简单Java类 private static Object getObject(Object actionObject, String attribute) throws NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //获取方法名 String meathodName = "get"+initCap(attribute); //1.调用指定属性的Field对象,在本类中取得对象类型,若不存在此属性则操作无法继续执行 Field field = actionObject.getClass().getDeclaredField(attribute); //2.在父类中获取该属性 if(field == null) { field = actionObject.getClass().getField(attribute); } //在本类和父类中均不存在该属性,则该对象不存在 if(field == null) { return null; } Method method = actionObject.getClass().getMethod(meathodName); return method.invoke(actionObject); } //根据类的对象设置类中属性,调用setter方法 public static void setObject(Object obj,String value, String temp) throws NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //1.调用指定属性的Field对象,在本类中取得对象类型,若不存在此属性则操作无法继续执行 Field field = obj.getClass().getDeclaredField(value); //2.在父类中获取该属性 if(field == null) { field = obj.getClass().getField(value); } //在本类和父类中均不存在该属性,则该对象不存在 if(field == null) { return; } //方法名的拼接 String methodName = "set"+initCap(value); Method setMethod = obj.getClass().getMethod(methodName, field.getType()); setMethod.invoke(obj, temp); } //实现首字母大写操作 public static String initCap(String value) { return value.substring(0, 1).toUpperCase()+value.substring(1); } }
EmpAction类设计:
package reflect; import java.lang.reflect.InvocationTargetException; //解耦合 public class EmpAction { private Emp emp = new Emp(); public void setValues(String value) throws NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { BeanOperation.setBeanValue(this,value); } public Emp getEmp() { return this.emp; } }
测试类设计:
package reflect; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /* * 反射与单级VO * */ public class Test { public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException { String value = "emp.name:lemon|emp.job:student"; EmpAction empAction = new EmpAction(); empAction.setValues(value); System.out.println(empAction.getEmp()); } }