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。