在Java中提供了reflect類,可以協助我們完成Java的類的屬性的遍曆,並且可以使用它完成屬性的修改。以下範例中提供了兩種操作方法:
1. 直接採用field.get和field.set操作
2. 使用Object.getClass().getMethod()方法擷取field的getter和setter,然後用method.invoke()實現
範例如下:
import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Constructor; public class TestJava{public static void reflectTest(Object model) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { // 擷取實體類的所有屬性,返回Field數組 Field[] field = model.getClass().getDeclaredFields(); // 遍曆所有屬性 for (int j = 0; j < field.length; j++) { // 擷取屬性的名字 String name = field[j].getName(); // 將屬性的首字元大寫,方便構造get,set方法 name = name.substring(0, 1).toUpperCase() + name.substring(1); // 擷取屬性的類型 String type = field[j].getGenericType().toString(); // 如果type是類類型,則前麵包含"class ",後面跟類名 System.out.println("屬性為:" + name); System.out.println("類型為:" + type);try{Class typeClass = field[j].getType(); //使用field的set和get進行操作。//對於private變數,一定要使用field.setAccessible(true);才可以進行訪問field[j].setAccessible(true);System.out.println("filed get 值為:" + field[j].get(model));if(typeClass == String.class){Constructor con = typeClass.getConstructor(typeClass); Object newvalue = null;newvalue = con.newInstance("20"); }else{field[j].set(model, 20);}System.out.println("filed set 後值為:" + field[j].get(model));//使用getMethod方法進行操作。//對於private變數,雖然在get時可以不使用getmethod.setAccessible(true)//但在setmethod的時候一定要調用setmethod.setAccessible(true)才可以進行修改。//另:從效率的角度上考慮,建議在getmethod時調用getmethod.setAccessible(true); System.out.println("方法名為:" + "Get" + name); Method getmethod = model.getClass().getMethod("Get" + name); getmethod.setAccessible(true); System.out.println("getmethod 值為:" + getmethod.invoke(model)); Method setmethod = model.getClass().getMethod("Set" + name, typeClass);setmethod.setAccessible(true);if(type.equals("class java.lang.String")) { setmethod.invoke(model, "test1"); } else {setmethod.invoke(model, 20); } System.out.println("set method 後值為:" + getmethod.invoke(model)); }catch(Exception e){ e.printStackTrace(); } } } public static void main(String[] args){try{TestClass test = new TestClass();test.SetA(0);test.SetB(21L);test.SetC("test");reflectTest(test);System.out.println();System.out.println();TestClass2 test2 = new TestClass2();test2.SetA(0);test2.SetB(21L);test2.SetC("test");reflectTest(test2);}catch(Exception e){}}}class TestClass{public int GetA() {return a;} public void SetA(int a) {this.a = a;}public long GetB() {return b;}public void SetB(long b) {this.b = b;}public String GetC() {return c;}public void SetC(String c) {this.c = c;}public double GetE() { return e;}public void SetE(double e) {this.e = e;}public float GetD() {return d;}public void SetD(float d) { this.d = d; }private int a;private long b;private String c;private double e;private float d;}class TestClass2{public Integer GetA() {return a;} public void SetA(Integer a) {this.a = a;}public Long GetB() {return b;}public void SetB(Long b) {this.b = b;}public String GetC() {return c;}public void SetC(String c) {this.c = c;}public Double GetE() { return e;}public void SetE(Double e) {this.e = e;}public Float GetD() {return d;}public void SetD(Float d) { this.d = d; }private Integer a;private Long b;private String c;private Double e;private Float d;}
reflect雖然提供了getter和setter的修改,但從效率上來說要比直接存取getter和setter的效率低,因此在選擇是否使用reflect做成員屬性的訪問修改,可以根據實際情況進行選擇。