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

简述

一直对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下的委托机制代码详解 的全部内容, 来源链接: utcz.com/z/353141.html

回到顶部