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());
}
}