Generating dynamic classes instead of reflections

Source: Internet
Author: User
Tags define abstract

improve the reflection efficiency can use the cache to do, another way is to generate dynamic classes can be directly called methods, performance and direct modulation, can replace reflection;

platform, a large number of use of reflection or dynamic generation of classes, generics, and other features, will greatly improve the platform universal line, not only save a lot of code, flexibility, improve performance, code looks very elegant;

1, first we need to define an abstract class, why to define abstract class, because we need to directly through it to call the target object's and function, so we have to clearly define the reference

Public abstract class MethodInvoker {public abstract object invoke (object instance, String method,object[] params);}
2 and then we top a factory that is used to create the proxy MethodInvoker class
public class Invokerfactory {public static MethodInvoker Createinvoker (class Clazz) throws exception{method[] methods = CL Azz.getdeclaredmethods ();          String className = Clazz.getname ();//Create class 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" + "I F (method==null| |                        Method==\ "\") \ n "+" return null;\n ";        The key here 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 ";                Add a Method Methodinvoker.addmethod (Ctnewmethod.make (methodstring, MethodInvoker));                Print the class name of the created class Object instance = Methodinvoker.toclass (). newinstance (); MethodinVoker invoker = (methodinvoker) instance; return invoker;}}

To explain, this is actually through reflection, analysis of the target class all methods, parameter type, parameter number, return value type, so as to match the incoming string, once matched to call that method directly

For example, for the user class, a dynamic method like this is generated.

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; }

I mean already at a glance, OK, we are actually using javassist to generate classes and methods, this class inherits the MethodInvoker abstract class, implements its Invoke method; then we'll be fine, then. Simply instantiate an object based on the class we generate, and then cast it to a methodinvoker reference, you can call it;


Using the generated dynamic class, the purpose of the direct call function is 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);}
is it convenient? Note that this invoke method, if you call the function has a return value, return, no return value returns NULL, and then passed the parameters in order to construct an array of parameters, currently I do not support array parameters and arrays returned, you can improve, Nothing but when the invoke function is generated, pay more attention to judge some special cases ha;


then, it is advisable to add a pooled object map in Methodfactory, because it takes time to generate this methodinvoker, which can be used universally, so it's better to save it to really improve performance .

I did a performance test.

Direct modulation: Dynamic generation: Reflection = 1:1:30

Generating dynamic classes instead of reflections

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.