通過(guò)反射實(shí)現(xiàn)Java下的委托機(jī)制代碼詳解
簡(jiǎn)述
一直對(duì)Java沒(méi)有現(xiàn)成的委托機(jī)制耿耿于懷,所幸最近有點(diǎn)時(shí)間,用反射寫(xiě)了一個(gè)簡(jiǎn)單的委托模塊,以供參考。
模塊API
public Class Delegater()//空參構(gòu)造,該類(lèi)管理委托實(shí)例并實(shí)現(xiàn)委托方法 //添加一個(gè)靜態(tài)方法委托,返回整型值ID代表該方法與參數(shù)構(gòu)成的實(shí)例。若失敗,則返回-1。 public synchronized int addFunctionDelegate(Class<?> srcClass,String methodName,Object... params); //添加一個(gè)實(shí)例方法委托,返回整型值ID代表該方法與參數(shù)構(gòu)成的實(shí)例。若失敗,則返回-1。 public synchronized int addFunctionDelegate(Object srcObj,String methodName,Object... params); //根據(jù)整型ID從委托實(shí)例中刪除一個(gè)方法委托,返回是否成功 public synchronized Boolean removeMethod(int registerID); //依次執(zhí)行該委托實(shí)例中的所有方法委托(無(wú)序) public synchronized void invokeAllMethod(); //將參數(shù)表轉(zhuǎn)換為參數(shù)類(lèi)型表 private Class<?>[] getParamTypes(Object[] params); //由指定的Class、方法名、參數(shù)類(lèi)型表獲得方法實(shí)例 private Method getDstMethod(Class<?> srcClass,String methodName,Class<?>[] paramTypes); class DelegateNode(Method refMethod,Object[] params)//DelegateNode類(lèi)在不使用Object構(gòu)造時(shí)敘述了一個(gè)靜態(tài)方法委托,包括方法實(shí)例及參數(shù)表 class DelegateNode(Object srcObj,Method refMethod,Object[] params)//DelegateNode類(lèi)在使用Object構(gòu)造時(shí)敘述了一個(gè)實(shí)例方法委托,包括類(lèi)實(shí)例、方法實(shí)例及參數(shù)表 public void invokeMethod(); //執(zhí)行該節(jié)點(diǎn)敘述的方法委托
源代碼
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Hashtable;
/**Delegater類(lèi)使用RTTI及反射實(shí)現(xiàn)Java下的委托機(jī)制
* @author 三向板磚
* */
public class Delegater {
static int register = Integer.MIN_VALUE;
//ID分配變量
Hashtable<Integer,DelegateNode> nodeTable;
//管理ID與對(duì)應(yīng)委托的容器
public Delegater()
{
nodeTable = new Hashtable<Integer,DelegateNode>();
}
//添加靜態(tài)方法委托
public synchronized int addFunctionDelegate(Class<?> srcClass,String methodName,Object... params)
{
Class<?>[] paramTypes = getParamTypes(params);
Method refMethod;
if((refMethod = getDstMethod(srcClass,methodName,paramTypes)) != null)
{
register++;
nodeTable.put(register,new DelegateNode(refMethod, params));
return register;
} else
{
return -1;
}
}
//添加動(dòng)態(tài)方法委托
public synchronized int addFunctionDelegate(Object srcObj,String methodName,Object... params)
{
Class<?>[] paramTypes = getParamTypes(params);
Method refMethod;
if((refMethod = getDstMethod(srcObj.getClass(),methodName,paramTypes)) != null)
{
register++;
nodeTable.put(register,new DelegateNode(srcObj,refMethod, params));
return register;
} else
{
return -1;
}
}
//刪除一個(gè)方法委托
public synchronized Boolean removeMethod(int registerID)
{
if(nodeTable.containsKey(registerID))
{
nodeTable.remove(registerID);
return true;
}
return false;
}
//無(wú)序地執(zhí)行委托方法
public synchronized void invokeAllMethod()
{
for (DelegateNode node:nodeTable.values())
{
node.invokeMethod();
}
}
//將參數(shù)表轉(zhuǎn)化為參數(shù)類(lèi)型表
private Class<?>[] getParamTypes(Object[] params)
{
Class<?>[] paramTypes = new Class<?>[params.length];
for (int i = 0;i < params.length;i++)
{
paramTypes[i] = params[i].getClass();
}
return paramTypes;
}
//根據(jù)Class類(lèi)實(shí)例、方法名、參數(shù)類(lèi)型表獲得一個(gè)Method實(shí)例
private Method getDstMethod(Class<?> srcClass,String methodName,Class<?>[] paramTypes)
{
Method result = null;
try {
result = srcClass.getMethod(methodName, paramTypes);
if(result.getReturnType() != void.class)
{
System.out.println("Warning,Method:"+methodName+" has a return value!");
}
}
catch (NoSuchMethodException | SecurityException e) {
System.out.println("Can Not Found Method:"+methodName+",ensure it's exist and visible!");
}
return result;
}
}
class DelegateNode
{
Object srcObj;
Method refMethod;
Object[] params;
public DelegateNode(Method refMethod,Object[] params)
{
this.refMethod = refMethod;
this.params = params;
}
public DelegateNode(Object srcObj,Method refMethod,Object[] params)
{
this.srcObj = srcObj;
this.refMethod = refMethod;
this.params = params;
}
public void invokeMethod()
{
try {
refMethod.invoke(srcObj,params);
}
catch (IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
System.out.println("Method:"+refMethod.toString()+" invoke fail!");
}
}
}
模塊測(cè)試
public class DelegaterTest {
public void showInfo()
{
System.out.println("Hello Delegate!");
}
public void showCustomInfo(String info)
{
System.out.println(info);
}
public static void showStaticInfo()
{
System.out.println("Static Delegate!");
}
public static void showCustomStaticInfo(String info)
{
System.out.println(info);
}
public static void main(String[] args) {
Delegater dele = new Delegater();
DelegaterTest tester = new DelegaterTest();
int ID = dele.addFunctionDelegate(tester,"showInfo");
dele.addFunctionDelegate(tester,"showCustomInfo","Custom!");
dele.addFunctionDelegate(DelegaterTest.class,"showStaticInfo");
dele.addFunctionDelegate(DelegaterTest.class,"showCustomStaticInfo","StaticCustom!");
dele.invokeAllMethod();
dele.removeMethod(ID);
System.out.println("------------------");
dele.invokeAllMethod();
}
}
執(zhí)行結(jié)果:
StaticCustom!
StaticDelegate!
Custom!
HelloDelegate!
------------------
StaticCustom!
StaticDelegate!
Custom!
其他事項(xiàng)
一些public方法使用synchronized是為了保證register變量的線程安全,使其不會(huì)因?yàn)槎嗑€程而出錯(cuò)。
對(duì)于有返回值的委托,會(huì)報(bào)出警告,但模塊還是接受這樣的委托的,不過(guò)在執(zhí)行委托時(shí)您將不能得到返回值。
添加的委托最大值是Integer.MAX_VALUE-Integer.MIN_VALUE超出后的容錯(cuò)處理沒(méi)有考慮(一般也沒(méi)這么多函數(shù)需要委托的吧。
委托執(zhí)行是無(wú)序的,而且,需要性能要求時(shí),委托的函數(shù)盡量不要有阻塞過(guò)程,否則會(huì)影響其他委托函數(shù)的執(zhí)行。
還有什么問(wèn)題可以發(fā)上來(lái)一同探討。
總結(jié)
以上就是本文關(guān)于通過(guò)反射實(shí)現(xiàn)Java下的委托機(jī)制代碼詳解的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他Java相關(guān)專(zhuān)題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!
相關(guān)文章
Java判斷一個(gè)字符串是不是一個(gè)數(shù)字的解決思路
這篇文章主要給大家介紹了關(guān)于Java判斷一個(gè)字符串是不是一個(gè)數(shù)字的解決思路,判斷一個(gè)字符串是否為數(shù)字是Java開(kāi)發(fā)中很常見(jiàn)的業(yè)務(wù)需求,實(shí)現(xiàn)這個(gè)判斷有很多種方式,需要的朋友可以參考下2023-08-08
java如何利用poi解析doc和docx中的數(shù)據(jù)
這篇文章主要給大家介紹了關(guān)于java如何利用poi解析doc和docx中數(shù)據(jù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
Java微信公眾平臺(tái)開(kāi)發(fā)(4) 回復(fù)消息的分類(lèi)及實(shí)體的創(chuàng)建
這篇文章主要為大家詳細(xì)介紹了Java微信公眾平臺(tái)開(kāi)發(fā)第四步,回復(fù)消息的分類(lèi)及實(shí)體的創(chuàng)建,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
Java NumberFormat 類(lèi)的詳解及實(shí)例
這篇文章主要介紹了Java NumberFormat 類(lèi)的詳解及實(shí)例的相關(guān)資料,數(shù)字格式化類(lèi)按照本地風(fēng)格習(xí)慣進(jìn)行的數(shù)字顯示,需要的朋友可以參考下2017-08-08
Spring AOP訪問(wèn)目標(biāo)方法的參數(shù)操作示例
這篇文章主要介紹了Spring AOP訪問(wèn)目標(biāo)方法的參數(shù)操作,結(jié)合實(shí)例形式詳細(xì)分析了spring面向切面AOP訪問(wèn)目標(biāo)方法的參數(shù)相關(guān)實(shí)現(xiàn)步驟與操作注意事項(xiàng),需要的朋友可以參考下2020-01-01
SpringBoot之多環(huán)境打包與配置文件排除方式
這篇文章主要介紹了SpringBoot之多環(huán)境打包與配置文件排除方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-04

