1. 程式人生 > >反射(reflect)

反射(reflect)

這樣的 指定 -- strong exception 驅動加載 pub ont exceptio

×

× 反射中類類型(ClassType)、類(class)、實例對象(Instance)的關系
技術分享

× 動態加載類

1 try {
2     Class c = Class.forName("className");//驅動加載也是長這樣的
3 } catch (ClassNotFoundException e) {
4     e.printStackTrace();
5 }

一、類類型(Class)的三種表現形式(一個類[class]只能有一個類類型對象[ClassType])

1 Class c = className.class;
2 Class c = classNameInstence.getClass;
3 Class c = Class.forName("類的全稱[packageName.className]");

二、通過獲取到的類類型對象進行實例創建(所創建的對象為class的實例,Class的實例)

className instance = (className) c.newInstance(); 
技術分享

三、獲取方法信息(函數的反射) -— java.lang.reflect.Method類
 相關函數 (c:類的類類型;getDeclaredXxx():不包括父類繼承而來,且自己聲明、不問訪問權限的成員)
   1. Method method = c.getMethod("methodName", parameterTypes); // 返回類中指定的public函數 。包括父類繼承而來的
   Method method = c.getDeclaredMethod(); //返回類中指定的自身聲明的函數,不包括父類繼承而來的
   2. Method[ ] method = c.getMethods(); // 獲取該類中所有public的方法,包括父類繼承而來的。
    Method[ ] method = c.getDeclaredMethods(); 獲取該類中所有該類自己聲明的方法,不問訪問權限。
演示代碼

 1         // Class c = className.class
 2         // Class c = Class.forName("");
 3         Class c = instance.getClass();// 獲取類類型對象
 4         System.out.println("類名稱:" + c.getName());
 5         Method[] mets = c.getMethods();// 獲取所有方法
 6         for (int i = 0; i < mets.length; i++) {
 7             Class returnType = mets[i].getReturnType();//
返回值類型的類類型 8 System.out.print(returnType.getName() + " ");// 獲取並輸出返回值類型 9 System.out.print(mets[i].getName() + "( ");// 獲取並輸出方法名稱 10 11 // 獲取參數類型 12 Class[] paramTypes = mets[i].getParameterTypes();// 返回參數列表的類型的類類型 13 for (int j = 0; j < paramTypes.length; j++) { 14 if (i == (paramTypes.length - 1)) { 15 System.out.print(paramTypes[j].getName()); 16 } else { 17 System.out.print(paramTypes[j].getName() + ","); 18 } 19 } 20 System.out.println(")"); 21 }

四、獲取變量信息(變量)

 1         // Class c = className.class
 2         // Class c = Class.forName("");
 3         Class c = obj.getClass();
 4         /*
 5          * 成員變量也是對象
 6          * java.lang.reflect.Field
 7          * Field類封裝了關於成員變量的操作
 8          * getFields()方法獲取的是所有的public的成員變量的信息
 9          * getDeclaredFields獲取的是該類自己聲明的成員變量的信息
10          */
11         //Field[] fs = c.getFields();
12         Field[] fs = c.getDeclaredFields();
13         for (Field field : fs) {
14             //得到成員變量的類型的類類型
15             Class fieldType = field.getType();
16             String typeName = fieldType.getName();
17             //得到成員變量的名稱
18             String fieldName = field.getName();
19             System.out.println(typeName+" "+fieldName);
20         }

五、獲取構造函數信息

 1         // Class c = className.class
 2         // Class c = Class.forName("");
 3         Class c = obj.getClass();
 4         /*
 5          * 構造函數也是對象
 6          * java.lang. Constructor中封裝了構造函數的信息
 7          * getConstructors獲取所有的public的構造函數
 8          * getDeclaredConstructors得到所有的構造函數
 9          */
10         //Constructor[] cs = c.getConstructors();
11         Constructor[] cs = c.getDeclaredConstructors();
12         for (Constructor constructor : cs) {
13             System.out.print(constructor.getName()+"(");
14             //獲取構造函數的參數列表--->得到的是參數列表的類類型
15             Class[] paramTypes = constructor.getParameterTypes();
16             for (Class class1 : paramTypes) {
17                 System.out.print(class1.getName()+",");
18             }
19             System.out.println(")");
20         }

六、方法的反射操作

1 method.invoke("對象",{參數列表}); //沒錯,就這樣...
2 //Object o = m.invoke(a1,new Object[]{10,20});
3  Object o = m.invoke(a1, 10,20);

通過反射機制了解泛型
* c1==c2結果返回true說明編譯之後集合的泛型是去泛型化的
* Java中集合的泛型,是防止錯誤輸入的,只在編譯階段有效,繞過編譯就無效了
* 驗證:我們可以通過方法的反射來操作,繞過編譯
* 結論:泛型盡在編譯時起作用,防止錯誤操作,與序列化有些相似

反射(reflect)