Java 反射與單級VO操作
阿新 • • 發佈:2019-01-27
反射與單級VO操作
先看一個基本程式
package www.bit.java.vo;
class Emp{
private String ename ;
private String job ;
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
@Override
public String toString() {
return "Emp{" + "ename='" + ename + '\'' + ", job='" + job + '\'' + '}';
}
}
public class TestDemo {
public static void main(String[] args) {
Emp emp = new Emp() ;
emp.setEname("zhangsan" ) ;
emp.setJob("Java Coder") ;
System.out.println(emp);
}
}
假設一個類中存在有幾十個屬性,要按照原始做法,要呼叫幾十次setter方法,這樣操作就太麻煩了。現在希望能對程式做簡化,輸入字串
“屬性名稱:屬性值|屬性名稱:屬性值|屬性名稱:屬性值|….”,
就可以將類中的屬性設定好。希望通過此程式實現任意的簡單Java類的屬性設定。
設計思路如下:
現在所有的操作是通過TestDemo類呼叫EmpAction類實現的,而EmpAction類的主要作用是在於定位要操作的屬性型別。同時該程式應該符合於所有簡單的Java類開發形式,因此對於我們的設計而言必須有一個單獨的類(BeanOperation)實現此適配。
例:Emp類設計(簡單Java類)
package test;
public class Emp {
private String ename;
private String job;
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
@Override
public String toString() {
return "Emp{" + "ename= " + ename + ", job= " + job + "}";
}
}
例:EmpAction類設計
package test;
import bit.util.BeanOperation;
public class EmpAction {
private Emp emp = new Emp();
public void setValue(String value) throws Exception {
//this表示EmpAction的物件
BeanOperation.setBeanValue(this, value);
}
public Emp getEmp() {
return emp;
}
}
例:BeanOperation類設計(公共程式類)
package bit.util;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//此類通過反射來進行簡單的java類的值插入
public class BeanOperation {
private BeanOperation() {}
//此方法用於給物件插入屬性
//emp.ename:zhangsan|emp.job:Coder
public static void setBeanValue(Object obj, String data) throws NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//當前obj表示EmpAction物件
//第一次拆分
String[] result = data.split("\\|");
for (int i = 0; i < result.length; i++) {
//emp.ename:zhangsan
String[] temp = result[i].split(":");
//取得要插入的資料
String value = temp[1];
//取得具體className emp
String className = temp[0].split("\\.")[0];
//取得具體屬性名
String fieldName = temp[0].split("\\.")[1];
Object realObject = getRealObject(obj, className);
//拿到具體操作的Emp類之後,開始呼叫具體的set方法來設定屬性
Class<?> realClass = realObject.getClass();
Method setMethod = realClass.getDeclaredMethod("set" + initCap(fieldName), String.class);
setMethod.invoke(realObject, value);
}
}
//
private static Object getRealObject(Object obj, String className) throws NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//拿到EmpAcrion類的Class物件
Class<?> cls = obj.getClass();
Field field = cls.getDeclaredField(className);
//在當前類中沒有找到此屬性
if(field == null) {
//再從父類中找此屬性
field = cls.getField(className);
if(field == null) {
return null;
}
}
//獲取get屬性名
String methodName = "get" + initCap(className);
Method getObjectMethod = cls.getDeclaredMethod(methodName);
//相當於呼叫empAction.getEmp();
return getObjectMethod.invoke(obj);
}
private static String initCap(String value) {
//將首字母大寫然後返回
return value.substring(0, 1).toUpperCase()+value.substring(1);
}
}
例:測試類設計
package test;
public class Test {
public static void main(String[] args) throws Exception {
String value = "emp.ename:zhangsan|emp.job:Conder";
EmpAction empAction = new EmpAction();
empAction.setValue(value);
System.out.println(empAction.getEmp());
}
}
這是上述測試類的執行結果