1. 程式人生 > >Java反射機制複習筆記

Java反射機制複習筆記

1.瞭解反射的基本原理
2.掌握class類的使用
3.使用Class類並結合java.lang.reflect包取得一個類的完整結構
4.通過反射機制動態的呼叫類中指定的方法,並能向這些方法中傳遞引數


核心概念:一切的操作都將使用object進行完成,包括類,陣列的應用都可以用object進行接收。


正常方式:引入包.類--通過new例項化物件--獲取例項化物件
反射方式:獲得例項化物件--getClass()方法獲得Class例項--得到完整的包.類名稱


java.lang.Class是java.lang.Object的派生類,前者繼承自後者。
在java中Object類是一切類的父類,那麼所有物件實際上
也就是java.lang.Class類的例項,所以所有物件都可以轉變為java.lang.Class型別表示。


例項化Class類物件:Class.forName(),類.class,物件.getClass();


用Class類物件本身例項化其他物件:
物件無參:用newInstance方法;
物件有引數:Constructor<?> con[] =Class.forName("com.evan.reflect.Person2").getConstructors();
呼叫Class例項的getConstrcuctors獲得一個Constructor陣列,再使用Constructor物件的newInstance()方法
例項化其他物件。得到的Object再進行向下轉型。






取得類結構:
Constuctors表示類中的構造方法;
Field表示類中的屬性;
Method表示類中的方法;
這三個都是AccessibleObject的子類它提供了將反射的物件標記為在使用時取消預設 Java 語言訪問控制檢查的能力


得到介面:Class<?>[] f = c.getInterfaces();
得到構造方法:Constructor<?>[] cons = c.getConstructors();(可直接打印出來)
構造方法拆分獲得:
Constructor<?>[] cons = c.getConstructors();
for (int i = 0; i < cons.length; i++) {
System.out.println(Modifier.toString(cons[i].getModifiers()));//把int變為許可權修飾符
System.out.println(cons[i].getName());//獲得方法名
Class<?>[] b = cons[i].getParameterTypes();//獲得引數
for (int j = 0; j < b.length; j++) {
System.out.print(b[j].getName() + " arg" + i);
if (j < b.length - 1) {
System.out.print(",");
} else {
System.out.println("){}");
}
}


}


得到父類:getSuperclass();
得到方法:Method[] m = c.getMethods();(可直接打印出來)
得到方法的返回值型別,異常型別: m[i].getReturnType().getName();
                                       Class<?>[] ex =m[i].getExceptionTypes();
                              ex[i].getName();
得到實現的介面或父類中的公共屬性:public Field[] getFileds();
                                      f[i].getModifiers(訪問許可權)/getName(屬性名)/getType(屬性型別);
得到本類中的全部屬性: public Filed[] getDeclaredFields();
                             f[i].getModifiers(訪問許可權)/getName(屬性名)/getType(屬性型別);
                             




通過反射訪問類中的方法。
 Class<?> c=Class.forName("......");
 Object obj = c.newInstance();
 Method med = c.getMethod("setCountry",String.class);
 med.invoke(obj,"haha");


setter getter 反射實現:
class GetClassDemo6 {
public static void main(String[] args) {
Object per = null;
try {
per =Class.forName("com.evan.reflect.Person4").newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {


e.printStackTrace();
} catch (ClassNotFoundException e) {


e.printStackTrace();
}
setter(per, "name", "sb", String.class);
setter(per, "age", 30, int.class);
getter(per, "name");
getter(per, "age");


}


public static void setter(Object obj, String arr, Object value, Class<?> type) {

try {
String s ="set"+up(arr);
Method met = obj.getClass().getMethod(s, type);
met.invoke(obj, value);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


}


public static void getter(Object obj, String arr) {


try {
String s ="get"+up(arr);
Method met = obj.getClass().getMethod(s);
System.out.println(met.invoke(obj));
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


}


public static String up(String arr) {
String s = arr.substring(0, 1).toUpperCase() + arr.substring(1);
return s;
}


}






反射運算元組:
得到陣列Class型別:Class<?> c = temp.getClass().getComponentType();
修改陣列大小:
public static void main(String[] args) {


int temp[] = { 1, 2, 3 };
// Class<?> c = temp.getClass().getComponentType();//獲得陣列元件型別的 Class
// System.out.println(c.getName());//返回陣列型別
int temp1[] = (int[]) arrayinc(temp, 5);
for (int i = 0; i < temp1.length; i++) {
System.out.println(temp1[i]);
}


}


public static Object arrayinc(Object obj, int len) {
Class<?> c = obj.getClass();
Class<?> a = c.getComponentType();
Object Onew = Array.newInstance(a, len);
int co = Array.getLength(obj);
System.arraycopy(obj, 0, Onew, 0, co);
//源陣列物件,從源下標位置開始,新數字,從新下標位置開始,複製源陣列長度
return Onew;


}

Array類反射操作包中表示一個數組
Array.newInstance(a, len);新建一個數組,a表示任意陣列元件型別的 Class物件
Array.getLength(obj);得到陣列長度
Array.set(Object array,int index,int value);修改制定下標的內容