天天看点

javassist:增强型的java反射工具,获取方法参数名

java的反射是不能获取方法的参数名的。比如:

publicStringconcatString(String param1,String param2){

returnparam1+param2;

}

想获取"param1",和"param2"这个参数名,貌似是不行的。借助第三方包javaassist就可以获得。

整合原作者代码:

Java代码

javassist:增强型的java反射工具,获取方法参数名
  1. importjavassist.ClassPool;
  2. importjavassist.CtClass;
  3. importjavassist.CtMethod;
  4. importjavassist.Modifier;
  5. importjavassist.NotFoundException;
  6. importjavassist.bytecode.CodeAttribute;
  7. importjavassist.bytecode.LocalVariableAttribute;
  8. importjavassist.bytecode.MethodInfo;
  9. publicclassTest{
  10. publicstaticvoidmain(String[]args){
  11. testReflectParamName();
  12. }
  13. publicstaticvoidtestReflectParamName(){
  14. Classclazz=MyClass.class;
  15. try{
  16. ClassPoolpool=ClassPool.getDefault();
  17. CtClasscc=pool.get(clazz.getName());
  18. CtMethodcm=cc.getDeclaredMethod("concatString");
  19. //使用javaassist的反射方法获取方法的参数名
  20. MethodInfomethodInfo=cm.getMethodInfo();
  21. CodeAttributecodeAttribute=methodInfo.getCodeAttribute();
  22. LocalVariableAttributeattr=(LocalVariableAttribute)codeAttribute
  23. .getAttribute(LocalVariableAttribute.tag);
  24. if(attr==null){
  25. //exception
  26. }
  27. String[]paramNames=newString[cm.getParameterTypes().length];
  28. intpos=Modifier.isStatic(cm.getModifiers())?0:1;
  29. for(inti=0;i<paramNames.length;i++)
  30. paramNames[i]=attr.variableName(i+pos);
  31. //paramNames即参数名
  32. for(inti=0;i<paramNames.length;i++){
  33. System.out.println("参数名"+i+":"+paramNames[i]);
  34. }
  35. }catch(NotFoundExceptione){
  36. e.printStackTrace();
  37. }
  38. }
  39. }
  40. classMyClass{
  41. publicStringconcatString(Stringparam1,Stringparam2){
  42. returnparam1+param2;
  43. }
  44. }

反射获取参数注解:

Java代码

javassist:增强型的java反射工具,获取方法参数名
  1. importjava.lang.annotation.Annotation;
  2. importjava.lang.annotation.ElementType;
  3. importjava.lang.annotation.Retention;
  4. importjava.lang.annotation.RetentionPolicy;
  5. importjava.lang.annotation.Target;
  6. importjava.lang.reflect.Method;
  7. importjava.util.Date;
  8. importjavassist.ClassPool;
  9. importjavassist.CtClass;
  10. importjavassist.CtMethod;
  11. importjavassist.Modifier;
  12. importjavassist.NotFoundException;
  13. importjavassist.bytecode.CodeAttribute;
  14. importjavassist.bytecode.LocalVariableAttribute;
  15. importjavassist.bytecode.MethodInfo;
  16. publicclassTest{
  17. publicstaticvoidmain(String[]args){
  18. testReflectParamName();
  19. //反射获取方法参数注解
  20. testReflectMethodParamAnno();
  21. }
  22. publicstaticvoidtestReflectParamName(){
  23. Classclazz=MyClass.class;
  24. try{
  25. ClassPoolpool=ClassPool.getDefault();
  26. CtClasscc=pool.get(clazz.getName());
  27. CtMethodcm=cc.getDeclaredMethod("concatString");
  28. //使用javaassist的反射方法获取方法的参数名
  29. MethodInfomethodInfo=cm.getMethodInfo();
  30. CodeAttributecodeAttribute=methodInfo.getCodeAttribute();
  31. LocalVariableAttributeattr=(LocalVariableAttribute)codeAttribute
  32. .getAttribute(LocalVariableAttribute.tag);
  33. if(attr==null){
  34. //exception
  35. }
  36. String[]paramNames=newString[cm.getParameterTypes().length];
  37. intpos=Modifier.isStatic(cm.getModifiers())?0:1;
  38. for(inti=0;i<paramNames.length;i++)
  39. paramNames[i]=attr.variableName(i+pos);
  40. //paramNames即参数名
  41. for(inti=0;i<paramNames.length;i++){
  42. System.out.println("参数名"+i+":"+paramNames[i]);
  43. }
  44. }catch(NotFoundExceptione){
  45. e.printStackTrace();
  46. }
  47. }
  48. publicstaticvoidtestReflectMethodParamAnno(){
  49. Classclazz=MyClass.class;
  50. try{
  51. //使用jdk原生的反射方法
  52. Methodm=clazz.getDeclaredMethod("datefomat",
  53. newClass[]{Date.class});
  54. Annotation[][]annotations=m.getParameterAnnotations();
  55. System.out.println("jdk获取方法参数anno:"+annotations[0][0]);
  56. }catch(SecurityExceptione){
  57. e.printStackTrace();
  58. }catch(NoSuchMethodExceptione){
  59. e.printStackTrace();
  60. }
  61. try{
  62. ClassPoolpool=ClassPool.getDefault();
  63. CtClasscc=pool.get(clazz.getName());
  64. CtMethodcm=cc.getDeclaredMethod("datefomat");
  65. //使用javassist的反射方法可以获得参数标注值
  66. Object[][]annotations=cm.getParameterAnnotations();
  67. DateFormatmyAnno=(DateFormat)annotations[0][0];
  68. System.out.println("参数注解:"+myAnno.value());
  69. }catch(NotFoundExceptione){
  70. e.printStackTrace();
  71. }catch(ClassNotFoundExceptione){
  72. e.printStackTrace();
  73. }
  74. }
  75. }
  76. classMyClass{
  77. publicStringconcatString(Stringparam1,Stringparam2){
  78. returnparam1+param2;
  79. }
  80. publicStringdatefomat(@DateFormat("yyyy-MM-ddHH")
  81. Datedate1){
  82. returndate1.toString();
  83. }
  84. }
  85. //注解类
  86. @Target(ElementType.PARAMETER)
  87. @Retention(RetentionPolicy.RUNTIME)
  88. @interfaceDateFormat{
  89. Stringvalue()default"yyyy-MM-dd";
  90. }