English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Sintesi
Ho sempre avuto un desiderio di avere un meccanismo di delega pronto in Java, fortunatamente ho avuto un po' di tempo recentemente, e ho scritto un modulo di delega semplice usando reflection per riferimento.
API del modulo
public Class Delegater()//Costruttore vuoto, questa classe gestisce le istanze delegate e implementa i metodi delegati //Aggiungi un metodo delegato statico, che restituisce un valore intero ID che rappresenta l'istanza del metodo con i parametri. In caso di fallimento, viene restituito -1. public synchronized int addFunctionDelegate(Class<?> srcClass, String methodName, Object... params); //Aggiungi un metodo delegato di istanza, che restituisce un valore intero ID che rappresenta l'istanza del metodo con i parametri. In caso di fallimento, viene restituito -1. public synchronized int addFunctionDelegate(Object srcObj,String methodName,Object... params); //Elimina una delega di metodo dall'istanza di delega in base all'ID intero, restituisce se con successo public synchronized Boolean removeMethod(int registerID); //Esegue in ordine i metodi di delega dell'istanza di delega (nessun ordine) public synchronized void invokeAllMethod(); //Convertisce la tabella dei parametri in una tabella dei tipi di parametri private Class<?>[] getParamTypes(Object[] params); //Ottiene l'istanza del metodo specificato da Class, nome del metodo e tabella dei tipi di parametri private Method getDstMethod(Class<?> srcClass,String methodName,Class<?>[] paramTypes); class DelegateNode(Method refMethod,Object[] params)//La classe DelegateNode descrive una delega di metodo statico utilizzando Object come costruttore, inclusa l'istanza del metodo e la tabella dei parametri class DelegateNode(Object srcObj,Method refMethod,Object[] params)//La classe DelegateNode descrive una delega di metodo di istanza utilizzando Object come costruttore, inclusa l'istanza della classe, l'istanza del metodo e la tabella dei parametri public void invokeMethod(); //Esegue la delega del metodo descritto da questo nodo
源代码
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Hashtable; /** La classe Delegater utilizza RTTI e reflection per implementare il meccanismo di delega in Java /* @author 三向板砖 /* */ public class Delegater { static int register = Integer.MIN_VALUE; //Variabile di assegnazione ID Hashtable<Integer,DelegateNode> nodeTable; //Gestisce il contenitore ID e delegato corrispondente public Delegater() { nodeTable = new Hashtable<Integer,DelegateNode>(); } //Aggiunge un metodo delegato statico 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; } } //Aggiunge un metodo delegato dinamico 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; } } //Elimina un metodo delegato public synchronized Boolean removeMethod(int registerID) { if(nodeTable.containsKey(registerID)) { nodeTable.remove(registerID); return true; } return false; } //Esegue in modo non ordinato i metodi delegati 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!"); } } }
Test modulo
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(); } }
Risultato dell'esecuzione:
StaticCustom!
StaticDelegate!
Custom!
HelloDelegate!
------------------
StaticCustom!
StaticDelegate!
Custom!
Altri aspetti
Alcuni metodi public utilizzano synchronized per garantire la sicurezza della variabile register, in modo che non venga influenzata da più thread e non si verifichino errori.
Per le deleghe con valore di ritorno, verrà emessa una avvertenza, ma il modulo accetta comunque tali deleghe, ma non è possibile ottenere il valore di ritorno durante l'esecuzione della delega.
Il valore massimo della delega aggiunta è Integer.MAX_VALUE-Integer.MIN_VALUE, e non è stata considerata la gestione di errore quando superato (forse non ci sono così tanti metodi che necessitano di delega, giusto?).
L'esecuzione della delega è disordinata e, quando ci sono esigenze di prestazioni, i metodi della delega non dovrebbero avere processi bloccanti, altrimenti influenzeranno l'esecuzione di altri metodi di delega.
Ci sono altre domande che possono essere inviate per essere discusse insieme.
Sommario
Questo è tutto il contenuto dettagliato dell'articolo su come implementare il meccanismo di delega in Java tramite riflessione, spero sia utile a tutti. Chi è interessato può continuare a leggere altri argomenti relativi a Java su questo sito, e se c'è qualcosa di insufficiente, è benvenuto a lasciare un commento. Grazie per il supporto degli amici a questo sito!
Dichiarazione: il contenuto di questo articolo è stato raccolto da Internet, il copyright è della proprietà del rispettivo proprietario, il contenuto è stato contribuito e caricato autonomamente dagli utenti di Internet, questo sito non detiene il diritto di proprietà, non è stato elaborato manualmente e non assume responsabilità legali correlate. Se trovi contenuti sospetti di violazione del copyright, invia un'e-mail a notice#oldtoolbag.com (sostituisci # con @ quando invii l'e-mail) per segnalare il problema e fornire prove pertinenti. Una volta verificata, questo sito eliminerà immediatamente il contenuto sospetto di violazione del copyright.