JAVA反射機制,先看下百度百科解釋
百度百科:
JAVA反射機制是在運作狀态中,對于任意一個實體類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意方法和屬性;這種動态擷取資訊以及動态調用對象方法的功能稱為java語言的反射機制。
JAVA反射(放射)機制:“程式運作時,允許改變程式結構或變量類型,這種語言稱為動态語言”。從這個觀點看,Perl,Python,Ruby是動态語言,C++,Java,C#不是動态語言。但是JAVA有着一個非常突出的動态相關機制:Reflection,用在Java身上指的是我們可以于運作時加載、探知、使用編譯期間完全未知的classes。換句話說,Java程式可以加載一個運作時才得知名稱的class,獲悉其完整構造(但不包括methods定義),并生成其對象實體、或對其fields設值、或喚起其methods。
簡單了解
通俗來講:就是java檔案編譯成class檔案後,jvm運作後将class檔案讀取并把它們加入到記憶體中,每個class配置設定了一個class對象(有且隻有一個即:後面執行個體化的對象都是同一個class對象)。在java.lang.Class 這個類中提供了一些方法來擷取這些class對象中的成員變量、屬性、方法等。
擷取方式
其中第3種方式用得較多,如:JDBC加載資料庫驅動用到。
- Object ——> getClass(); 用父類Object建立。
- 類.class屬性擷取,如:Class userClass = User.class;
- Class userClass= Class.forName(“com.User”);//注意此字元串必須是真實路徑(包路徑.類),
常用方法
-
1.加載
Class class= Class.forName(“com.User”);
構造方法:
-
2.擷取所有公有構造方法
Constructor[] conArray = class.getConstructors();
-
3.擷取所有的構造方法(包括:私有、受保護、預設、公有)
conArray = class.getDeclaredConstructors();
for(Constructor c : conArray){
System.out.println©;
}
-
4.擷取公有、無參的構造方法
Constructor con = class.getConstructor();
//調用構造方法
Object obj = con.newInstance();
-
5.擷取私有構造方法,并調用
con = class.getDeclaredConstructor(char.class);
//調用構造方法
con.setAccessible(true);//暴力通路(忽略掉通路修飾符)
obj = con.newInstance(‘A’);
成員變量:
-
6.擷取所有公有的字段
Field[] fieldArray = stuClass.getFields();
for(Field f : fieldArray){
System.out.println(f);
}
-
7.擷取所有的字段(包括私有、受保護、預設的)
fieldArray = class.getDeclaredFields();
for(Field f : fieldArray){
// 擷取字段中帶有某個注解屬性(可用于自定義注解,如擷取導出字段相關屬性用于導入導出,ExcelAnnotation :自定義excel注解)
ExcelAnnotation excelAnnotation = f
.getAnnotation(ExcelAnnotation.class);
if (excelAnnotation != null) {
System.out.println(f+" 字段帶有ExcelAnnotation 注解屬性");
}
System.out.println(f);
}
-
8.擷取公有字段,并調用
Field f = class.getField(“name”);
System.out.println(f);
//擷取一個對象
Object obj = class.getConstructor().newInstance();// 相當于new User()
//為字段設定值
f.set(obj, “李四”);
-
9.擷取私有字段,并調用
f = class.getDeclaredField(“phoneNum”);
System.out.println(f);
f.setAccessible(true);//暴力反射,解除私有限定
f.set(obj, “18888889999”);
擷取成員方法并調用:
-
10.擷取所有的”公有“方法
Method[] methodArray = class.getMethods();
for(Method m : methodArray){
System.out.println(m);
}
-
11.擷取所有的方法,包括私有的
Method[] methodArray = class.getDeclaredMethods();
-
12.擷取公有的test()方法
Method m = class.getMethod(“test”, String.class);
System.out.println(m);
-
13.擷取私有的test2()方法
m = class.getDeclaredMethod(“test2”, int.class);//int.class是參數類型
System.out.println(m);
m.setAccessible(true);//解除私有限定
Object result = m.invoke(obj, 20);//需要兩個參數,一個是要調用的對象(擷取有反射),一個是實參
System.out.println(“傳回值:” + result);
-
14.調用某個類的某個方法
public void Test(String s){
System.out.print(“Test方法被調用”+s);
}
//通過反射擷取Class對象
Class class= Class.forName(“cn.com.test.User”);
//2擷取Test()方法
Method m = class.getMethod(“Test”);
//3.調用Test()方法
m.invoke(class.getConstructor().newInstance(),“是我調用的”);