最近看了看反射斩披,反射涉及的知識還是很廣的溜族,這里我們只是簡單的了解一下。
反射機制
首先我們來了解一下反射的原理垦沉。
具體參考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();
那我們應該如何調(diào)用這個類對象的方法呢癞尚?
//1、獲取方法的 Method 對象
Method setPriceMethod = clz.getMethod("setPrice", int.class);
//2榜配、利用 invoke 方法調(diào)用方法
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ā)好爪瓜,比如插件程序。
還可能是要在運行期從配置文件讀取類名匙瘪,這時候就沒有辦法硬編碼铆铆。