java也是一門編譯型語言,但凡的是編譯型語言,都有著不靈活的一面澎怒,不能像js這樣的解釋性語言的動態(tài)化,但是編譯型語言都有強(qiáng)大的運行時,而反射就是java的運行時的體現(xiàn)阶牍。
下面看一個簡單的Demo
public static void printClassMethodMessage(Object obj){
Class s = obj.getClass();
System.out.println(s.getName());
//獲取所有的方法數(shù)組
Method[] ms = s.getMethods();
for (int i=0;i<ms.length;i++){
//獲取該方法的返回值類型
Class returnType = ms[i].getReturnType();
//返回值類型的名字
System.out.print(returnType.getName()+ " ");
//方法名
System.out.print(ms[i].getName()+"(");
//獲取該方法所有的參數(shù)
Class[] paramTypes = ms[i].getParameterTypes();
for (Class class1: paramTypes ) {
//獲取每個參數(shù)的類名
System.out.print(class1.getName()+",");
}
System.out.println(")");
}
}
最后看一下編譯和運行時的差異
public static void main (String[] args) {
//普通數(shù)組
ArrayList list = new ArrayList();
//只能保存字符串的數(shù)組
ArrayList<String> list1 = new ArrayList<String>();
list1.add("hello");//可以添加
// list1.add(20); //編譯錯誤
Class c1 = list.getClass();
Class c2 = list1.getClass();
System.out.println(c1==c2);
try {
Method m = c2.getMethod("add", Object.class); //利用反射獲取數(shù)組 add 方法
m.invoke(list1,20); //方法調(diào)用
System.out.println(list1.size()); //大小為2
System.out.println(list1);
for (Object ob: list1 ) {
System.out.println(ob); //正常
}
for (String str: list1 ) {
System.out.println(str);// 報錯
}
}catch (Exception e){
e.printStackTrace();
}
}
上面的例子說明了喷面,編譯時和運行時的差別,運行時是有黑魔法的走孽,它可以繞過編譯去進(jìn)行一些編譯器不允許的操作惧辈。
反射的使用場景在spring框架是很廣泛的,例如AOP面向切面編程和動態(tài)代理...