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

Durch Reflection die Delegation in Java umsetzen - Code-Detailanalyse

Kurzbeschreibung

Die bestehenden Delegationssysteme in Java haben mich immer gestört, glücklicherweise hatte ich kürzlich etwas Zeit, eine einfache Delegationsschicht mit Reflection zu schreiben, um sie zur Verfügung zu stellen.

Modul API

public Class Delegater()//Leerer Konstruktor, die Klasse verwaltet Delegation Instanzen und implementiert Delegation Methoden 
//Fügt eine statische Methoden-Delegation hinzu, gibt die Integer-ID zurück, die durch diese Methode und die Parameter构成。Fehlschlägt, gibt zurück-1. 
public synchronized int addFunctionDelegate(Class<?> srcClass, String methodName, Object... params);
//Fügt eine Instanzmethoden-Delegation hinzu, gibt die Integer-ID zurück, die durch diese Methode und die Parameter构成。Fehlschlägt, gibt zurück-1. 
public synchronized int addFunctionDelegate(Object srcObj, String methodName, Object... params);
//Löscht eine Methoden-Delegation aus der Delegation Instanz basierend auf dem Integer ID, gibt zurück, ob der Vorgang erfolgreich war 
public synchronized Boolean removeMethod(int registerID);
//Führt alle Methoden-Delegationen in der angegebenen Delegation Instanz nacheinander aus (unsortiert) 
public synchronized void invokeAllMethod();
//Konvertiert das Parameterarray in eine Tabellentypenliste 
private Class<?>[] getParamTypes(Object[] params);
//Erhält eine Methodeninstanz durch angegebene Class, Methodenname und Tabellentypen der Parameter 
private Method getDstMethod(Class<?> srcClass, String methodName, Class<?>[] paramTypes);
class DelegateNode(Method refMethod, Object[] params)//Die Klasse DelegateNode beschreibt eine statische Methoden-Delegation, wenn Object nicht als Konstruktor verwendet wird, einschließlich der Methodeninstanz und des Parameterarrays 
class DelegateNode(Object srcObj, Method refMethod, Object[] params)//Die Klasse DelegateNode beschreibt eine Instanzmethoden-Delegation bei der Verwendung von Object als Konstruktor, einschließlich der Klasseinstanz, der Methodeninstanz und des Parameterarrays 
public void invokeMethod();
//Führt die Delegation des beschriebenen Knotens aus

Quellcode

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Hashtable;
/**Die Klasse Delegater verwendet RTTI und Reflection, um das Delegationsmechanismus in Java zu implementieren 
 * @author 三向板砖 
 * */
public class Delegater {
	static int register = Integer.MIN_VALUE;
	//ID allocation variable 
	Hashtable<Integer,DelegateNode> nodeTable;
	//manage the container of ID and corresponding delegate 
	public Delegater() 
	  {
		nodeTable = new Hashtable<Integer,DelegateNode>();
	}
	//add static method delegate 
	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;
		}
	}
	//add dynamic method delegate 
	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;
		}
	}
	//delete a method delegate 
	public synchronized Boolean removeMethod(int registerID) 
	  {
		if(nodeTable.containsKey(registerID)) 
		    {
			nodeTable.remove(registerID);
			return true;
		}
		return false;
	}
	//unorderedly execute the delegate method 
	public synchronized void invokeAllMethod() 
	  {
		for (DelegateNode node: nodeTable.values()) 
		    {
			node.invokeMethod();
		}
	}
	//Konvertiert eine Parameter-Tabelle in eine Tabelle der Parameter-Typen 
	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;
	}
	//ermittelt eine Methode-Instanz basierend auf einem Class-Objekt, einem Methodennamen und einer Tabelle der Parameter-Typen 
	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("Warnung, Methode:")+methodName+" hat einen Rückgabewert!");
			}
		}
		catch (NoSuchMethodException | SecurityException e) {
			System.out.println("Kann Methode nicht finden:")+methodName+"
sicherstellen, dass es existiert und sichtbar ist!");
		}
		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("Methode:",+refMethod.toString()+"Aufruf fehlgeschlagen!");
		}
	}
}

Modultest

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相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

声明:本文内容来源于网络,版权归原作者所有。内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:notice#oldtoolbag.com(在发邮件时,请将#更换为@)进行举报,并提供相关证据。一经查实,本站将立即删除涉嫌侵权内容。

Empfohlene Artikel