一般情況下物件屬性的存取只能操作公開(public)的方法或屬性,有時候有某些情況需要操作被設計為private 的方法或屬性的時候可以透過反射機制進行。
以下將利用反射機制,來修改與設定目標物件的屬性。
首先先製作一個類別
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public class Student { private int id; private String name; private boolean male; private double account; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isMale() { return male; } public void setMale(boolean male) { this.male = male; } public double getAccount() { return account; } public void setAccount(double account) { this.account = account; } } |
以下程式會透過反射機制對資料進行修改,首先先取得目標的反射物件,透過setAccessible將該屬性的權限改為可修改,並利用set方法給予值,實作程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
public class Test { public static void main(String[] args) { // TODO Auto-generated method stub Student student = new Student(); Class<?> clazz = student.getClass(); try { Field id = clazz.getDeclaredField("id"); System.out.println("設定前的 id = " + student.getId()); id.setAccessible(true); id.setInt(student, 10); System.out.println("設定後的 id = " + student.getId()); System.out.println(); Field name = clazz.getDeclaredField("name"); System.out.println("設定前的 name = " + student.getName()); name.setAccessible(true); name.set(student, "haha"); System.out.println("設定後的 name = " + student.getName()); System.out.println(); Field male = clazz.getDeclaredField("male"); System.out.println("設定前的 male = " + student.isMale()); male.setAccessible(true); male.setBoolean(student, true); System.out.println("設定後的 male = " + student.isMale()); System.out.println(); Field account = clazz.getDeclaredField("account"); System.out.println("設定前的 account = " + student.getAccount()); account.setAccessible(true); account.setDouble(student, 148.24); System.out.println("設定後的 account = " + student.getAccount()); System.out.println(); } catch (NoSuchFieldException | SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } |
實驗成果如下,預設時沒有資料,透過反射機制賦予目標屬性資料。
完整專案(連結)
文章標籤
全站熱搜