簡述
一直對Java沒有現成的委託機制耿耿於懷,所幸最近有點時間,用反射寫了一個簡單的委託模塊,以供參考。
模塊API
public Class Delegater()//空參構造,該類管理委託實例並實現委託方法//添加一個靜態方法委託,返回整型值ID代表該方法與參數構成的實例。若失敗,則返回-1。 public synchronized int addFunctionDelegate(Class<?> srcClass,String methodName,Object... params);//添加一個實例方法委託,返回整型值ID代表該方法與參數構成的實例。若失敗,則返回-1。 public synchronized int addFunctionDelegate(Object srcObj,String methodName,Object... params);//根據整型ID從委託實例中刪除一個方法委託,返回是否成功public synchronized Boolean removeMethod(int registerID);//依次執行該委託實例中的所有方法委託(無序) public synchronized void invokeAllMethod();//將參數表轉換為參數類型表private Class<?>[] getParamTypes(Object[] params);//由指定的Class、方法名、參數類型表獲得方法實例private Method getDstMethod(Class<?> srcClass,String methodName,Class<?>[] paramTypes);class DelegateNode(Method refMethod,Object[] params)//DelegateNode類在不使用Object構造時敘述了一個靜態方法委託,包括方法實例及參數表class DelegateNode(Object srcObj,Method refMethod,Object[] params)//DelegateNode類在使用Object構造時敘述了一個實例方法委託,包括類實例、方法實例及參數表public void invokeMethod();//執行該節點敘述的方法委託
原始碼
import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Hashtable;/**Delegater類使用RTTI及反射實現Java下的委託機制* @author 三向板磚* */public class Delegater {static int register = Integer.MIN_VALUE;//ID分配變量Hashtable<Integer,DelegateNode> nodeTable;//管理ID與對應委託的容器public Delegater() {nodeTable = new Hashtable<Integer,DelegateNode>();}//添加靜態方法委託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;}}//添加動態方法委託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;}}//刪除一個方法委託public synchronized Boolean removeMethod(int registerID) {if(nodeTable.containsKey(registerID)) {nodeTable.remove(registerID);return true;}return false;}//無序地執行委託方法public synchronized void invokeAllMethod() {for (DelegateNode node:nodeTable.values()) {node.invokeMethod();}}//將參數表轉化為參數類型表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;}//根據Class類實例、方法名、參數類型表獲得一個Method實例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!");}}}模塊測試
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();}}執行結果:
StaticCustom!
StaticDelegate!
Custom!
HelloDelegate!
------------------
StaticCustom!
StaticDelegate!
Custom!
其他事項
一些public方法使用synchronized是為了保證register變量的線程安全,使其不會因為多線程而出錯。
對於有返回值的委託,會報出警告,但模塊還是接受這樣的委託的,不過在執行委託時您將不能得到返回值。
添加的委託最大值是Integer.MAX_VALUE-Integer.MIN_VALUE超出後的容錯處理沒有考慮(一般也沒這麼多函數需要委託的吧。
委託執行是無序的,而且,需要性能要求時,委託的函數盡量不要有阻塞過程,否則會影響其他委託函數的執行。
還有什麼問題可以發上來一同探討。
總結
以上就是本文關於通過反射實現Java下的委託機制代碼詳解的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站其他Java相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!