最近看了看反射,反射涉及的知識還是很廣的,這里我們只是簡單的了解一下。
反射機制
首先我們來了解一下反射的原理。
具體參考https://www.cnblogs.com/chanshuyi/p/head_first_of_reflection.html,這篇博文是我認為最容易讓人理解反射的一篇博文了。
首先有“反”,就有“正”,什么是正?
構建一個Apple類,包含了price屬性:
public class Apple {
private int price;
public Apple() {
}
public Apple(int price) {
this.price = price;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "Apple{" +
"price=" + price +
'}';
}
}
正常來說,我們是使用 new關鍵字初始化一個對象,我們稱為“正射”:
Apple apple = new Apple();
問題來了,如果我們不知道一開始要初始化的類對象是什么的話怎么辦?
//1、獲取類的 Class 對象實例
Class clz = Class.forName("com.zhudan.reflex.Apple");
//2、根據(jù) Class 對象實例獲取 Constructor 對象
Constructor appleConstructor = clz.getConstructor();
//3、使用 Constructor 對象的 newInstance 方法獲取反射類對象
Object appleObj = appleConstructor.newInstance();
那我們應該如何調用這個類對象的方法呢?
//1、獲取方法的 Method 對象
Method setPriceMethod = clz.getMethod("setPrice", int.class);
//2、利用 invoke 方法調用方法
setPriceMethod.invoke(appleObj, 5);
//同理
Method getPriceMethod = clz.getMethod("getPrice");
getPriceMethod.invoke(appleObj);
//同理
Method toStringMethod = clz.getMethod("toString");
System.out.println(toStringMethod.invoke(appleObj));
進一步的,我自己寫了一個構造函數(shù),用過構造函數(shù)給屬性賦值,該怎么做?
//獲取Constructor的時候加上參數(shù)的類型,反射創(chuàng)造的時候賦值
Class clzNew = Class.forName("com.zhudan.reflex.Apple");
Constructor appleConstructorNew = clzNew.getConstructor(int.class);
Object appleObjNew = appleConstructorNew.newInstance(14);
Method toStringMethodNew = clz.getMethod("toString");
System.out.println(toStringMethodNew.invoke(appleObjNew));
有人問了,為什么要用反射實例化對象,什么場景會用到反射機制呢?
反射是為了增加程序的靈活性。
有可能創(chuàng)建對象的程序比要創(chuàng)建的對象先開發(fā)好,比如插件程序。
還可能是要在運行期從配置文件讀取類名,這時候就沒有辦法硬編碼。