在前面的文章中(http://www.linuxidc.com/Linux/2012-01/51222.htm)提到了类反射的瓶颈原因,为了避免大量简单类型的转型,大量的数组产生,提出解决方案首先sun的method.invoke 是不可用了,因为invoke 的使用本来产生了大量的数组为了参数。
- invoke(Object obj, Object... args)
解决方案一般我们类反射通常这样写:Class="testclass" Method="testmethod" args[0].type="int" value="1" arg[1].type="long" value=1 arg[2].type="byte" value="3" return="void"构建arg 的基础类
- public class arg{
- public int int1;
- public int int2;
- ...
- public long long1;
- public long long2;
- ...
- public byte byte1;
- ......
- }
构建method 的基础类,第三个参数是代表返回的类型
- public abstract class method{
- public abstract Object invoke(Object obj, arg args, Object o);
- public abstract int invoke(Object obj,arg args, int i);
- public abstract void invoke(Object obj, arg args)
- public abstract args map(Object parameter);
-
- }
然后分析刚才的arg[]的类型,大小,使用 ClassFileAssembler 生成一个虚拟的method1的类继承method,直接生成字节码,并且load到JVM里
而生成的class源码应该类似
- public class method1 extends method{
- public void invoke(Object obj, arg args){
- test test = (test)obj;
- test.testmethod(args.int1,args.long1,arg.type1);
- }
- ThreadLocal local = new ThreadLocal();
- local.put(args);
- public void map(Object parameter){
- arg args = (arg)local.get();
- args.Long1= 1;
- ....
- }
- }
对args的参数赋值是在虚拟类里面直接赋值的,同时为了避免object args每次大量生成,可以吧object args 放入threadlocal, 绑定到线程,每次取出直接赋值就可以了。