生成动态类代替反射

提高反射效率可利用缓存来搞,另一种方法是,生成动态类的方式可直接调用方法,性能跟直接调一样,可代替反射;

做平台,大量使用反射或者动态生成类,泛型,等特性,会极大地提高平台通用行,不仅节省众多代码,灵活性高,提高性能,代码看起来也是非常的优雅;

1,首先我们需要定义个抽象类,为什么要定义抽象类呢,因为我们需要直接通过它去调用目标对象的和函数,所以要明确定义出来还引用嘛

public abstract class MethodInvoker {


	public abstract Object invoke(Object instance, String method,Object[] params);
}

2,然后我们顶一个工厂,用于创建代理MethodInvoker类

public class InvokerFactory {


	public static MethodInvoker createInvoker(Class clazz) throws Exception{

		Method[] methods = clazz.getDeclaredMethods();
		String className = clazz.getName();

	// 创建类  
        ClassPool pool = ClassPool.getDefault();  
        CtClass methodInvoker = pool.makeClass("test.MethodInvokerImpl",pool.getCtClass("test.MethodInvoker"));
        
        
        String methodString = "public Object invoke(Object instance, String method,Object[] params) \n"
        		+ "{\n"
        		+ "	if(method==null||method==\"\") \n"
        		+ "	return null;\n" ;
        
        
        //关键在这里
        for(int i=0;i<methods.length;i++){
        	Method method = methods[i];
        	Class returnType = method.getReturnType();
        	
        	String methodName = method.getName();
        	int paramCount = method.getParameterCount();
        	Class[] parameterTypes = method.getParameterTypes();
        	
        	methodString = methodString + "	if(method.equals(\""+methodName+"\")) \n";
        	
        	if(returnType.getName().equals("void")){
        		methodString = methodString + "	{ \n";
        		methodString = methodString + "		(("+className+")instance)."+methodName+"(";
        	}
        	else
        		methodString = methodString + "		return (("+className+")instance)."+methodName+"(";
        	for(int j=0;j<paramCount;j++){
        		Class cls = parameterTypes[j];
        		methodString = methodString +"("+cls.getName()+")params["+j+"]";
        		if((j+1)<paramCount)
        			methodString = methodString +",";
        	}
        	methodString = methodString +"); \n";
        	
        	if(returnType.getName().equals("void")){
        		methodString = methodString + "		return null; \n";
        		methodString = methodString + "	} \n";
        	}
        }
        
		methodString = methodString	+ "	return null; \n"
		+ "}\n";
        
        // 添加一个方法
        methodInvoker.addMethod(CtNewMethod.make(methodString, methodInvoker));
        
        // 打印创建类的类名 
        Object instance = methodInvoker.toClass().newInstance();
        
        MethodInvoker invoker = (MethodInvoker)instance;

        return invoker;
	}
}

解释一下,这里面其实就是通过反射,分析目标类所有的方法,参数类型,参数个数,返回值类型,从而好根据传入的字符串匹配,一旦匹配到了就直接调用那个方法

例如,对于User这个类来说,会生成一个这样的动态方法出来

public Object invoke(Object instance, String method,Object[] params) 
{
	if(method==null||method=="") 
	return null;
	if(method.equals("setUsername")) 
	{ 
		((test.User)instance).setUsername((java.lang.String)params[0]); 
		return null; 
	} 
	if(method.equals("getUsername")) 
		return ((test.User)instance).getUsername(); 
	if(method.equals("getPassword")) 
		return ((test.User)instance).getPassword(); 
	if(method.equals("setPassword")) 
	{ 
		((test.User)instance).setPassword((java.lang.String)params[0]); 
		return null; 
	} 
	return null; 
}

我的意思已经一目了然了吧,ok,我们实际上就是用javassist来生成类和方法的,这个类继承了MethodInvoker抽象类,实现了它的invoke方法;那么接下来,我们就很好办了,只需要根据我们生成的类实例化一个对象,然后强制转换成MethodInvoker引用,就可以调用了;


        //采用生成动态类,达到直接调用函数的目的
	public static void main(String[] args) throws Exception {
		User user = new User();
		MethodInvoker invoker = InvokerFactory.createInvoker(user.getClass());
		Object[] array = {"xingzai"};
		invoker.invoke(user, "setUsername",array );	
	}

是不是很方便呢;注意,这个invoke方法,如果你调用的函数有返回值,就return,没返回值就返回null;然后传入的参数按顺序构造一个参数数组,目前我这个例子还不支持数组参数和数组返回,大家可以改进一下,无非在生成invoke函数时,多注意判断一些特殊情况哈;


然后,建议大家最好在MethodFactory里,增加一个池化对象map;因为生成这个methodInvoker也是需要耗费时间的,这玩意可以通用,因此还是保存起来好一些,才能真正意义上提升性能

我做了一个性能测试

直接调:动态生成调:反射 = 1:1:30

转载于:https://my.oschina.net/glarystar/blog/483657

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值