当前位置: 移动技术网 > IT编程>开发语言>Java > 通过反射实现Java下的委托机制代码详解

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

2019年07月19日  | 移动技术网IT编程  | 我要评论

简述

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网