java之反射Reflect
阿新 • • 發佈:2019-01-14
1.Class類的使用
(1)java中普通的資料型別類和靜態的成員不屬於物件。
(2)類也是物件,是java.lang.Class類的例項物件。
(3)Class類本身是無法new自身的。因為可以從原始碼看到:
Class類本身的構造方法是一個私有的構造方法,只有java虛擬機器可以來呼叫。
(4)Class類的使用程式碼:
package function.reflect; /** * Class類的使用 * * @author kimtian */ public class ClassUsed { public static void main(String[] args) { //Student 物件的例項 Student student1 = new Student(); //Student這個類也是一個例項物件,是Class類的例項物件 //任意一個類都是Class的例項物件,這個例項物件有三種表示方式 //第一種表示方式-->任何一個類都有一個隱含的靜態成員變數class Class c1 = Student.class; System.out.println(c1); //第二種表達方式 已經知道該類的物件,通過getClass方法呼叫 Class c2 = student1.getClass(); //第三種表達方式 Class c3 = null; try { c3 = Class.forName("function.reflect.Student"); } catch (ClassNotFoundException e) { e.printStackTrace(); } System.out.println(c2 == c3); /** * c1,c2表示了Student類的類型別(ClassType) * 萬事萬物皆物件 * 類也是物件,是Class類的例項物件 * 這個物件我們稱為該類的類型別 */ // 不管c1 or c2 都代表了foo類的類型別,一個類只可能是Class類的一個例項物件 System.out.println(c1 == c2); //我們完全可以通過類的類型別建立該類的例項物件。-->通過c1 or c2 or c3建立Student的例項 Student student2 = null; try { //需要有無引數的構造方法,否則會報錯 student2 = (Student) c1.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } class Student { }
2.動態載入類
(1)從上面可以看到 Class.forName("類的全稱") 可以用來建立類的例項。
c1.newInstance();不僅表示了類的類型別,還代表了動態載入類;
編譯時刻載入類是靜態載入類、執行時刻載入類是動態載入類,我們在做一些通過功能方法的時候最好使用動態載入類。
(2)靜態載入類的實現:
由於使用的靜態載入類,如果我們沒有Office類,那麼在編譯Office類的時候就會出錯。
如果有一個類似於Word、Excel這樣的類出錯,全部其他的功能都使用不了。
package function.reflect; /** * 如果有一個出問題,全部其他的功能也都使用不了 * 每次增加新功能,要修改基礎程式碼 * * @author kimtian */ public class Office { public static void main(String[] args) { if ("Word".equals(args[0])) { //new建立物件是靜態載入類,在編譯時刻就需要載入所有可能使用到的類。 //只想在執行哪個時候載入哪個,就要使用動態載入類 Word word = new Word(); word.start(); } if ("Excel".equals(args[0])) { Excel excel = new Excel(); excel.start(); } } }
(3)動態載入類的實現:
使用動態載入類,如果要使用Excel,但是沒有Excel類,則只在執行的時候才會報錯。但不會影響其他的,如Word的使用。
我們給定一個OfficeAble的通用介面,使Word、Excel等都實現該介面,可擴充套件性好,新增類似其他的功能時,只需要增加新的程式碼實現OfficeAble通用介面。不用重新修改編譯這個功能基礎類。
package function.reflect;
/**
* 如果需要加其他OfficeAble的具體實現,也不需要重新修改編譯這個類
*
* @author kimtian
*/
public class OffiiceBetter {
public static void main(String[] args) {
try {
//動態載入類,在執行時刻載入
Class c = Class.forName(args[0]);
//通過類型別,建立該類物件
OfficeAble oa = (OfficeAble) c.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}