您好,登錄后才能下訂單哦!
簡述
一直對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相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。