一、什麼是反射技術?
動態獲取指定類以及類中的內容(成員),並運行其內容。
應用程序已經運行,沒法在其中進行new對象的創建,就沒法使用對象。這時能夠根據配置文件的類全名去找對應的字節碼文件,並加載進內存,並建立該類對象實例。這就須要使用反射技術完成數組
二、獲取class對象的三種方式
獲取Class對象的方式一:
經過對象具有的getClass方法(源於Object類的方法)。有點不方便,須要用到該類,並建立該類的對象,再調用getClass方法完成。函數
Person p = new Person();//建立Peron對象 Class clazz = p.getClass();//經過object繼承來的方法(getClass)獲取Person對應的字節碼
文件對象code
獲取Class對象的方式二:對象
每個類型都具有一個class靜態屬性,經過該屬性便可獲取該類的字節碼文件對象。比第一種簡單了一些,僅用一個靜態屬性就搞定了。可是,仍是有一點不方便,還必需要使用到該類。 Class clazz = Person.class;
獲取Class對象方式三:繼承
* 去找找Class類中是否有提供獲取的方法呢? * 找到了,static Class forName(className); * 相對方便的多,不須要直接使用具體的類,只要知道該類的名字便可。 * 而名字完成能夠做爲參數進行傳遞 ,這樣就能夠提升擴展性。 * 因此爲了動態獲取一個類,第三種方式最爲經常使用。 Class clazz = Class.forName("com.bean.Person");//必須類全名
建立Person對象的方式
之前:內存
1.先加載com.bean.Person類進內存。 2.將該類封裝成Class對象。 3.根據Class對象,用new操做符建立com.bean.Person對象。 4.調用構造函數對該對象進行初始化。 com.bean.Person p = new com.bean.Person();
經過方式三:(此外還可使用構造,構造能夠指定參數---如String.class)get
String className = "com.bean.Person";
//1,根據名稱獲取其對應的字節碼文件對象it
1,經過forName()根據指定的類名稱去查找對應的字節碼文件,並加載進內存。 2,並將該字節碼文件封裝成了Class對象。 3,直接經過newIntstance方法,完成該對象的建立。 4,newInstance方法調用就是該類中的空參數構造函數完成對象的初始化。 Class clazz = Class.forName(className);
//2,經過Class的方法完成該指定類的對象建立。ast
Object object = clazz.newInstance();//該方法用的是指定類中默認的空參數構造函數完成的初始化。
清單1,獲取字節碼文件中的字段。class
Class clazz = Class.forName("cn.itcast.bean.Person"); //獲取該類中的指定字段。好比age Field field = clazz.getDeclaredField("age");//clazz.getField("age"); //爲了對該字段進行操做,必需要先有指定類的對象。 Object obj = clazz.newInstance();//對私有訪問,必須取消對其的訪問控制檢查,使用AccessibleObject父類中的 setAccessible的方法 field.setAccessible(true);//暴力訪問。建議你們儘可能不要訪問私有 field.set(obj, 789);//獲取該字段的值。 Object o = field.get(obj); System.out.println(o);
備註:
getDeclaredField:獲取全部屬性,包括私有。 getField:獲取公開屬性,包括從父類繼承過來的,不包括非公開方法。
清單2,獲取字節碼文件中的方法。
//根據名稱獲取其對應的字節碼文件對象
Class clazz = Class.forName("com.bean.Person");
//調用字節碼文件對象的方法getMethod獲取class對象所表示的類的公共成員方法(指定方法),參數爲方法名和當前方法的參數,無需建立對象,它是靜態方法
Method method = clazz.getMethod("staticShow", null);
//調用class對象所表示的類的公共成員方法,須要指定對象和方法中的參數列表
method.invoke(null, null);
………………………………………………………………………………………………………
Class clazz = Class.forName("com.bean.Person"); //獲取指定方法。 Method method = clazz.getMethod("publicShow", null); //獲取指定的類對象。 Object obj = clazz.newInstance(); method.invoke(obj, null);//對哪一個對象調用方法,是參數組
好處:大大的提升了程序的擴展性。