我這樣理解反射
- 反射是什麼?
反射是java的核心技術點之一,也是諸多java框架的基石之一。學習之前,先看其定義:
JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法,這種動態獲取、調用對象方法的功能稱爲java語言的反射機制。
通過定義,可以看出反射是在運行狀態中作用,對象可以通過反射的方式動態獲取和調用任意一個類的方法、屬性等。
- 反射如何使用?
首先看一下我們正常要使用一個對象,是如何使用,一般地,我們定義一個類,給他賦值,可以在其他類中new出這個對象,然後調用對象中定義的屬性和方法。代碼如下:
package com.jbzhang.refdemo;
public class RefTest {
public static void main(String[] args) {
User user=new User();
//h獲取屬性
user.setUsername("jbzhang");
//獲取方法
user.getUserBy();
}
}
那麼反射怎麼做呢?其實反射要做的事情就是從類或對象中推導出Class類,然後再從Class類中獲得類的信息。
- 如何獲取class類?
在上面的例子中class類是User類的類。獲取它有三種方式,如下:
//如果已經獲取到類,通過靜態變量獲取class
Class c1=User.class;
//如果知道對象,通過getclass()獲取類
Class c2=user.getClass();
//通過forname()獲取
Class c3=Class.forName("com.jbzhang.refdemo.User");
System.out.println(c1==c3); //c1 c2 c3 都是一樣的
System.out.println(c1.getName()); //com.jbzhang.refdemo.User 獲取類的名字,包含包名
System.out.println(c1.getSimpleName());//User 獲取類的名字
我們得到了User的class類,那麼就可以通過class獲取很多需要的信息。比如類裏面的方法、屬性、構造函數等。下面的代碼都有體現。
public class ClassUtil {
public static void printClass() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class c=Class.forName("com.jbzhang.refdemo.User");
//獲取類的所有方法,有兩種方式
/**
* getDeclaredMethods() 獲取這個類自己聲明的方法
* getMethods() 獲取所有public 的方法,包括父類的
*/
Method[] m=c.getDeclaredMethods();
//Method[] m1=c.getMethods();
for (int i=0;i<m.length;i++){
//得到所有方法的返回值
Class cs=m[i].getReturnType();
System.out.println("方法的返回值是"+cs.getName());
//得到方法的名稱
System.out.println("方法名是:"+m[i].getName());
//獲得的參數類型
Class[] par=m[i].getParameterTypes();
for(int j=0;j<par.length;j++){
System.out.println("方法的參數類型"+par[i].getName()+",");
}
}
/**
* 獲取成員變量的數組
* getFields() 獲取所有public 的成員變量的信息
* getDeclaredFields() 獲取該類自己聲明的變量
*/
Field[] fs=c.getFields();
Field[] fs1=c.getDeclaredFields();
//獲取構造方法的數組
Constructor[] cst=c.getConstructors();
for(int k=0;k<cst.length;k++){
//獲取構造方法的參數類型
Class[] cpars=cst[k].getParameterTypes();
}
//獲取特定的方法
Method method=c.getMethod("getUserBy");
//方法調用
method.invoke(c);
}
}