反射的原理和實現
阿新 • • 發佈:2019-01-28
反射:
反射應用在一些通用性比較高的程式碼中。
一般的框架,大多數都是使用反射來實現的。
在框架開發中,都是基於配置檔案開發。
在配置檔案紅配置了類,可以通過反射得到類中的所有內容,可以讓類中某個方法執行。
類中所有的內容:屬性、沒有引數的構造方法、有引數的構造方法、普通方法。
分析反射的原理:
首先把需要java檔案儲存到本地硬碟 .java檔案
編譯java檔案成 .class檔案
使用jvm,把class檔案通過類載入載入到記憶體中
萬事萬物都是物件,class檔案在記憶體中使用class類表示
當使用反射的時候,首先需要獲取到class 類,得到這個類之後,就可以得到class檔案裡的所有內容。
-包含屬性,構造方法,普通方法
屬性通過一個類 Filed
構造方法通過一個類 Construction
普通方法通過一個類 Method
使用反射操作類裡面的無引數的構造方法:
首先獲取到Class類
//獲取Class類的三種方式 Class class1 = testDemoperson.class; Class class2 = new testDemoperson().getClass(); Class class3 = Class.forName("test04.testDemoperson");
比如:要對一個類進行例項化,可以new,不使用new,怎麼獲取?
//得到Class
Class c3 = Class.forName("test04.testDemoperson");
//得到testDemoperson類例項
testDemoperson p = (testDemoperson) c3.newInstance();
使用反射操作有引數的構造方法:
publicstaticvoid test2() throws Exception{ //得到Class Class c1 = Class.forName("test04.testDemoperson"); //使用有引數的構造方法 //c1.getConstructor();//獲取所有的構造方法。 //傳遞有引數的構造方法裡面的引數型別,型別使用class形式傳遞 Constructor cs = c1.getConstructor(String.class,String.class); //通過有引數的構造方法設定值 //通過有引數的構造方法建立person例項 testDemoperson p8 = (testDemoperson) cs.newInstance("lisi","200"); System.out.println(p8.getId()+" "+p8.getName()); }
使用反射來操作屬性:
publicstaticvoid test3() throws Exception {
//得到Class類
Class c9 = Class.forName("test04.testDemoperson");
//得到name屬性
//得到testDemoperson的例項
testDemoperson p11 = (testDemoperson) c9.newInstance();
//通過這個方法得到屬性,引數是屬性的名稱
Field f = c9.getDeclaredField("name");
//操作的是私有的屬性,不讓操作,設定可以操作私有屬性setAccessible(true);
f.setAccessible(true);
//設定name值 set方法,兩個引數:第一個是引數的例項,第二個是設定的值。
f.set(p11, "王5");//相當於在 p.name = "王5";
System.out.println(f.get(p11));//相當於p.name
}
使用反射操作普通方法:
使用Method類表示普通方法
publicstaticvoid test6() throws Exception{
//得到Class類
Class c5 = Class.forName("test04.testDemoperson");
//得到testDemoperson例項
testDemoperson p7 = (testDemoperson) c5.newInstance();
//得到普通的方法
//c5.getDeclaredMethods();//得到所有的普通方法
//傳遞兩個引數:第一個引數是方法名稱,第二個引數是通過方法設定的值
Method m4 = c5.getDeclaredMethod("setName", String.class);
//讓setName方法執行,執行設定值
//使用invoke(p4,"張");
//傳遞兩個引數,第一個是testDemoperson的例項,第二個引數是設定的值
//執行了invoke方法之後,相當於執行了setName方法,同時通過這個方法設定了一個值叫“張”
m4.invoke(p7, "張");
System.out.println(p7.getName());
}
注意:
操作私有的方法,需要設定值是true
m4.setAccessible(true);
當操作的方法是靜態的方法的時候,因為靜態方法呼叫方式是類名.方法名,
不需要類的例項。使用反射操作靜態方法的時候也是不需要例項的。
在invokie方法的第一個引數裡面,寫一個null
m4.invoke(null,“張”);