我是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 衡锋 阅读(8226) 评论(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)

这个就是说在运行时保证可以获取到该注解信息,
你现在的做法放射肯定得不到啊  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: