English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Implementazione del meccanismo di delega in Java tramite reflection: spiegazione dettagliata del codice

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.

Ti potrebbe interessare