English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Resumen
Siempre tengo una preocupación por la falta de un mecanismo de delegación listo para usar en Java, afortunadamente, últimamente he tenido un poco de tiempo para escribir un módulo de delegación simple, a modo de ejemplo.
API del módulo
public Class Delegater()//Constructor sin parámetros, esta clase gestiona las instancias de delegación y realiza métodos de delegación //Agregar una delegación de método estático, devolver el valor entero ID representado por este método y los parámetros. Si falla, devolver-1。 public synchronized int addFunctionDelegate(Class<?> srcClass,String methodName,Object... params); //Agregar una delegación de método de instancia, devolver el valor entero ID representado por este método y los parámetros. Si falla, devolver-1。 public synchronized int addFunctionDelegate(Object srcObj,String methodName,Object... params); //Eliminar un método de delegación de la instancia de delegación según el ID entero, devolver si tiene éxito public synchronized Boolean removeMethod(int registerID); //Ejecutar sucesivamente todos los métodos de delegación de la instancia de delegación (desordenados) public synchronized void invokeAllMethod(); //Convertir la tabla de parámetros en la tabla de tipos de parámetros private Class<?>[] getParamTypes(Object[] params); //Obtener la instancia del método a partir de la tabla de tipos de parámetros especificada por la clase, el nombre del método y la tabla de tipos de parámetros private Method getDstMethod(Class<?> srcClass,String methodName,Class<?>[] paramTypes); class DelegateNode(Method refMethod,Object[] params)//La clase DelegateNode describe una delegación de método estático sin usar Object en la construcción, que incluye la instancia del método y la tabla de parámetros class DelegateNode(Object srcObj,Method refMethod,Object[] params)//La clase DelegateNode describe un método de delegación de instancia utilizando Object en la construcción, que incluye la instancia de la clase, la instancia del método y la tabla de parámetros public void invokeMethod(); //Ejecutar el método delegado descrito en este nodo
Código fuente
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Hashtable; /**La clase Delegater utiliza RTTI y reflexión para implementar el mecanismo de delegación en 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(); } } //Convertir la tabla de parámetros en la tabla de tipos de parámetros 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; } //Obtener una instancia de Method a partir de la instancia de Class, el nombre del método y la tabla de tipos de parámetros 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("Advertencia, método:")+methodName+" tiene un valor de retorno!"); } } catch (NoSuchMethodException | SecurityException e) { System.out.println("No se puede encontrar el método:")+methodName+"asegúrate de que exista y sea 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("Método:");+refMethod.toString()+"invocación fallida!"); } } }
Módulo de prueba
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(); } }
Resultados de la ejecución:
StaticCustom!
StaticDelegate!
Custom!
HelloDelegate!
------------------
StaticCustom!
StaticDelegate!
Custom!
Otras cuestiones
Algunos métodos públicos utilizan synchronized para garantizar la seguridad de la variable register, para que no falle debido a múltiples hilos.
Para las delegaciones con valor de retorno, se emitirá una advertencia, pero el módulo aún acepta tales delegaciones, aunque no se puede obtener el valor de retorno en la ejecución de la delegación.
El valor máximo de la delegación agregada es Integer.MAX_VALUE-No se ha considerado el manejo de errores después de que Integer.MIN_VALUE se exceda (¿no necesitan tantos métodos de delegación, generalmente?).
La ejecución de la delegación es desordenada y, cuando se requieren requisitos de rendimiento, los métodos de delegación no deben tener procesos bloqueantes, de lo contrario afectará la ejecución de otros métodos de delegación.
¿Hay alguna otra pregunta que pueda subir para discutir juntos?
Resumen
Este es el contenido completo del artículo sobre la implementación del mecanismo de delegación en Java a través de reflexión, espero que sea útil para todos. Los amigos interesados pueden continuar leyendo otros temas relacionados con Java en este sitio, y si hay deficiencias, por favor déjenos un mensaje. Gracias a todos por su apoyo a este sitio!
Declaración: El contenido de este artículo se obtiene de la red, es propiedad del autor original, el contenido se contribuye y sube por los usuarios de Internet, este sitio no posee los derechos de propiedad, no se ha procesado editorialmente por humanos y no asume responsabilidades legales relacionadas. Si encuentra contenido sospechoso de infracción de derechos de autor, por favor envíe un correo electrónico a: notice#oldtoolbag.com (al enviar un correo electrónico, por favor reemplace # con @) para denunciar y proporcionar evidencia relevante. Una vez verificada, este sitio eliminará inmediatamente el contenido sospechoso de infracción.