java 通過反射操作對象

1、類的加載

 一般來說,java程序在主動使用某個類時,若該類沒有加載到內存中,JVM會通過加載,連接,初始化三個階段對該類進行初始化。
 類加載到系統後就是一個java.lang.Class對象,例如:
 我有一個Person類,該類沒有在內存中,當我執行:Person p = new Person();時,類加載器會將Person類加載到系統,並持有一個Class對象。
 類加載器通常不會等到詩詞使用某個類時才加載該類,java虛擬機一般會預先加載某些類在內存中,比如我們常用的系統工具類,String,Map,等工具類都是預先加載的。
 

 2、獲得Class對象

  通常有如下三種方式:
1)使用Class類的forName(String clazzName)靜態方法。這裏的clazz必須的完整路徑,比如:com.test.Person
2)調用某個類的class屬性來獲得該類的Class對象。例如: Class clazz = Person.class;
3)調用某個對象的getClass方法。例如:
Person p = new Person();
Class clazz = p.getClass();

3、通過反射操作對象

1)先創建com.test.Person類:
public class Person {
private String name = "gonjan";
private Integer age = 24;

public void print() {
System.out.println("name:" + name + " age:" + age);
}

public void say(String content) {
System.out.println(name + " say :" + content);
}

private void privateSay(String content) {
System.out.println(name + "say :" + content);
}

}
2)當獲得某個類對應的Class對象後,就可通過該Class對象來獲取該類的全部或指定方法,全部或指定成員變量。
獲得Class對象1:
Class clazz = Class.forName("com.test.Person");

獲得Class對象2:
Person p1 = new Person();
Class clazz = Person.class;

獲得Class對象3:
Person p1 = new Person();
Class clazz = p1.getClass();

   通過class對象獲得Person中所有的方法:
Method[] methods = clazz.getMethods();

通過class對象獲得對象方法,並調用
Method mt = clazz.getMethod("say", String.class);
mt.invoke(p1, "通過反射調用對象public方法!");

通過反射獲得類中的私有方法,並可以通過setAccessible來取消其私有權限(ps:單例模式中,可以通過這方式打破私有構造方法保證只有一個對象)
Method mt2 = clazz.getDeclaredMethod("privateSay", String.class);
mt2.setAccessible(true);  //取消了privaeSay方法的private權限
mt2.invoke(p1, "通過反射調用對象private方法!");//通過invoke方法來調用類中的方法


通過Filed中的方法使類中私有成員變量可見。
Field ageField = clazz.getDeclaredField("age");
ageField.setAccessible(true);
ageField.set(p1, 30);//這裏可以直接更改p中的私有成員變量



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章