反射機制:(Class類)reflect
Class cl = Date.class//字節碼:
1.如何得到各個字節碼對應的實例對象(Class類型)
1.類名。class,for example, System.class-------->得到SYSTEM類對應的字節碼
2.對象.getClass(), for example, new Date().getClass-------->得到Date這個對象的字節碼。
3.Class.forName("類名"), for example, Class.forName("java.Util.Date");類加載器,將指定的類加載進來。數據庫連接時要用到的。
2.基本概念:
反射就是把JAVA類中的各種成分映射成相應的JAVA類。例如,一個JAVA類中用一個Class類的對象來表示,一個類中的組成部分:成員變量,
方法,構造方法,包等等信息也用一個個的JAVA類來表示,就像汽車是一個類,汽車中的發動機,變速箱等等也是一個個的類。
表示JAVA類的Class類顯然要提供一系列的方法,來獲取其中的變量,方法,構造方法,修飾符,包等信息,這些信息就是用
相應類的實例對象來表示,他們是Filed,Method,Contructor,Package等等。
一個類中的每個成員都可以用相應的反射Api類的一個實例對象來表示,通過調用Class類的方法可以得到這些實例對象後,得到這些實例
對象後有什麼用呢??怎麼用呢?這正是學習和應用反射的要點
Construct類(構造方法類)
得到指定的構造方法:Construtor constructor1 = Class.forName("java.lang.String").getConstrutor();
得到所有的構造方法:Construtor[] constructors Class.forName("java.lang.String").getConstrutors();
for example: 我們要寫一個new String(new StringBuffer("abc"));
首先:我們必須利用反射拿到String對應的構造方法類中指定的構造方法;
即:Constrctor c1 = Class.forName("java.lang.String").getContructor(Buffere.class)
其次:利用返回的構造方法類創建的相應的構造方法的實例:
即:String str = (String)c1.newInstance(new StringBuffere("abc"));
注意:兩次出現的StringBuffere的意義是不同的。前者是在確定得到的是哪個構造方法,後者是作爲參數傳遞的,參與實例的初始化過程。
Field類(成員變量類)
Point p1 = new Point(3,5);
Field fieldY = p1.getClass(p1).getField("y");
注意:此時得到的值並不是某個對象的值(比如5),而是得到的是類的一個成員變量。要想得到具體的值,必須映射到某個具體的對象上去;
for example: fieldY.get(p1)==5; 此時得到的就是具體的值了。因爲它映射到了具體的p1對象上去了。
如果該成員變量(X)是私有的(private),那麼就必須要用特定的方法去拿私有的了變量了,
for example: Field fieldX = p1.getClass(p1).getDeclaredField("x"); 就算拿到了也不能直接訪問的到。還要進行設置;
fieldX.setAccessible(true);此時該私有的成員變量就可以被訪問了;
fieldX == 3;
Method類(成員方法類)
Method類代表某個類中的一個成員方法
得到類中的某個方法:
例子:Method charAt = Class.forName("java.lang.String").getMethod("charAt",int.Class);
調用方法:
通常方式:System.out.println(str.charAt(1));
反射的方式:System.out.println(charAt.invoke(str,1));
如果傳遞給Method對象的invoke()方法的第一個參數爲null,說明該Method對象對應的是一個靜態方法。
對接受數組參數的成員方法進行反射:
for example: main()調用的例子: Person.main(new String[]{"111","2222"});
String startingClassName = args[0];
Method mainMethod = Class.forName(startingClassName).getMethod("main",String[].class);
mainMethod.invoke(null,(object)new String[]{"111","222"});//在傳遞參數的時候一定不要忘了(object)不然會編譯出錯,因爲這樣會讓編譯器拆開數組進行3個對象的傳遞
javaBean(內省)
String propertyName = "x"; //x--->X--->getX--->MethodGetX--->
使用反射和內省後:
1.PropertyDescriptor pd = new PropertyDescriptor(propertyName,Person.getClass)//得到變量的屬性值。
2.Method methodGetX = pd.getReadMethod();//通過反射和內省得到相應方法
3.Obeject retVal = methodGetX.invoke(p);//調用方法,完成所有的步驟。