欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

通过反射实现Java下的委托机制代码详解

程序员文章站 2023-12-15 15:53:40
简述 一直对java没有现成的委托机制耿耿于怀,所幸最近有点时间,用反射写了一个简单的委托模块,以供参考。 模块api public class delega...

简述

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

上一篇:

下一篇: