我是FE,也是Fe

          前端來源于不斷的點滴積累。我一直在努力。

          統計

          留言簿(15)

          閱讀排行榜

          評論排行榜

          javassist:增強型的java反射工具,獲取方法參數名,獲取方法參數標注值

          java的反射是不能獲取方法的參數名的。比如:

          public String concatString(String param1,String param2){
                  
          return param1+param2;
              }

          想獲取"param1",和"param2"這個參數名,貌似是不行的。借助第三方包javaassist就可以獲得。

           1     public static void main(String[] args) {
           2         Class clazz = 
           3 MyClass.class;
           4         try {
           5             ClassPool pool = ClassPool.getDefault();  
           6             CtClass cc = pool.get(clazz.getName());  
           7             CtMethod cm = cc.getDeclaredMethod("concatString");
           8             
           9             //使用javaassist的反射方法獲取方法的參數名
          10             MethodInfo methodInfo = cm.getMethodInfo();  
          11             CodeAttribute codeAttribute = methodInfo.getCodeAttribute();  
          12             LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);  
          13             if (attr == null)  {
          14                 //exception
          15             }
          16             String[] paramNames = new String[cm.getParameterTypes().length];  
          17             int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;  
          18             for (int i = 0; i < paramNames.length; i++)  
          19                 paramNames[i] = attr.variableName(i + pos);      
          20             //paramNames即參數名
          21             for (int i = 0; i < paramNames.length; i++) {
          22                 System.out.println(paramNames[i]);
          23             }
          24             
          25         } catch (NotFoundException e) {
          26             e.printStackTrace();
          27         } 
          28     }


          第一次使用覺得這個東西蠻神奇的。今天我在用反射獲取標注值時,發現使用jdk本身的反射貌似也獲取不到。我又想到了javassist,他果然沒讓我失望。
           1     public String datefomat(@DateFormat("yyyy-MM-dd HH")Date date1){
           2         return date1.toString();
           3     }
           4     
           5     public static void main(String[] args) {
           6         Class clazz =MyClass.class;
           7         try {
           8             //使用jdk原生的反射方法
           9             Method m = clazz.getDeclaredMethod("datefomat"new Class[]{Date.class});
          10             Annotation[][] annotations = m.getParameterAnnotations();
          11             System.out.println(annotations[0]);
          12 //            Annotation anno = annotations[0][0]; // index outof range  exception
          13         } catch (SecurityException e) {
          14             e.printStackTrace();
          15         } catch (NoSuchMethodException e) {
          16             e.printStackTrace();
          17         }
          18         
          19         try {
          20             ClassPool pool = ClassPool.getDefault();  
          21             CtClass cc = pool.get(clazz.getName());  
          22             CtMethod cm = cc.getDeclaredMethod("datefomat");
          23             
          24             //使用javassist的反射方法可以獲得參數標注值
          25             Object[][] annotations = cm.getParameterAnnotations();
          26             DateFormat myAnno =(DateFormat) annotations[0][0];
          27             System.out.println(myAnno.value());
          28             
          29             
          30             
          31             
          32         } catch (NotFoundException e) {
          33             e.printStackTrace();
          34         } catch (ClassNotFoundException e) {
          35             e.printStackTrace();
          36         }
          37         
          38         
          39         
          40     }

          Annotation的定義:
           1 package ;
           2 
           3 import java.lang.annotation.ElementType;
           4 import java.lang.annotation.Target;
           5 
           6 @Target(ElementType.PARAMETER)   
           7 public @interface DateFormat {
           8     String value() default "yyyy-MM-dd";
           9 }
          10 


          問題是解決了。回頭想想,不知道為什么jdk提供的getParameterAnnotations方法就不行(bug? I do not know) 我的jdk版本是1.5.0_17-b04。

          posted on 2010-10-25 17:53 衡鋒 閱讀(8261) 評論(10)  編輯  收藏 所屬分類: j2ee

          評論

          # re: javassist:增強型的java反射工具,獲取方法參數名,獲取方法參數標注值 2010-11-13 19:19 陽衡鋒

          getParameterAnnotations之所以沒有獲得到DateFormat 的實例,是因為DateFormat 的定義沒有:
          @Retention(RetentionPolicy.RUNTIME)
          所以運行時不會獲取Annotation對象

            回復  更多評論   

          # re: javassist:增強型的java反射工具,獲取方法參數名,獲取方法參數標注值 2011-09-15 08:31 tb

          貌似很強大啊   回復  更多評論   

          # re: javassist:增強型的java反射工具,獲取方法參數名,獲取方法參數標注值[未登錄] 2012-06-21 11:54 java

          補充一點,這種獲取參數名的方法,需要在編譯時指定vars,即在編譯時將變量名稱信息附加到字節碼中,否則javassist也無能為力  回復  更多評論   

          # re: javassist:增強型的java反射工具,獲取方法參數名,獲取方法參數標注值 2012-07-06 16:56 tfzzh

          勉強的用 自建注解的方式處理了該問題  回復  更多評論   

          # re: javassist:增強型的java反射工具,獲取方法參數名,獲取方法參數標注值 2013-01-20 00:10 Unmi

          確實是很有用,記得原來曾經思考過一個根據參數名來確定執行邏輯的實現,但是反射,包括一些 Aspect 實現攔截時也做不到,所以未能達成,下回看有這個需求的時候,可以考慮用下 javaassit。  回復  更多評論   

          # re: javassist:增強型的java反射工具,獲取方法參數名,獲取方法參數標注值 2013-06-04 16:12 tb

          貌似方法不錯的  回復  更多評論   

          # re: javassist:增強型的java反射工具,獲取方法參數名,獲取方法參數標注值[未登錄] 2014-02-26 11:31 wind

          使用Spring的:
          LocalVariableTableParameterNameDiscoverer variableDiscover = new LocalVariableTableParameterNameDiscoverer();
          String[] params = variableDiscover.getParameterNames(declaredMethod);  回復  更多評論   

          # re: javassist:增強型的java反射工具,獲取方法參數名,獲取方法參數標注值[未登錄] 2014-09-16 15:06 xx

          getParameterAnnotations方法 只能獲取運行時的Annotations ,在你自己的Annotations上加上@Retention(RetentionPolicy.RUNTIME)應該就能獲取了  回復  更多評論   

          # re: javassist:增強型的java反射工具,獲取方法參數名,獲取方法參數標注值 2014-12-10 17:00 foru

          CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
          我在這一步,codeAttribute就是null了,這個是什么原因啊?  回復  更多評論   

          # re: javassist:增強型的java反射工具,獲取方法參數名,獲取方法參數標注值 2014-12-17 10:15 唐思

          因為你的注解Dateformat類沒有加上@Retention(RetentionPolicy.RUNTIME)

          這個就是說在運行時保證可以獲取到該注解信息,
          你現在的做法放射肯定得不到啊  回復  更多評論   

          主站蜘蛛池模板: 西平县| 商河县| 汉阴县| 浙江省| 海口市| 永州市| 田阳县| 天峻县| 潼南县| 平谷区| 金门县| 潍坊市| 永兴县| 康定县| 瓮安县| 布尔津县| 克山县| 贺兰县| 乌拉特后旗| 富锦市| 孙吴县| 庆安县| 介休市| 滨海县| 涞源县| 清水河县| 安福县| 颍上县| 卢龙县| 迭部县| 汉川市| 襄垣县| 田东县| 丹东市| 璧山县| 桐乡市| 金川县| 嘉黎县| 迁安市| 家居| 临泉县|