📜  Java8 参数反映(1)

📅  最后修改于: 2023-12-03 14:42:21.807000             🧑  作者: Mango

Java8 参数反射

随着Java8版本的推出,反射相关的API也得到了更多的优化和增强。本文将重点介绍Java8中参数反射相关的内容。

一、Parameter类

Java8中新增加了一个Parameter类,该类用于描述方法参数的信息。

1、获取方法参数信息
Method method = Demo.class.getMethod("test", String.class, int.class);
Parameter[] parameters = method.getParameters();
for (Parameter parameter : parameters) {
    System.out.println(parameter.getName()); // 打印参数名
    System.out.println(parameter.getType()); // 打印参数类型
}
2、获取参数名

通过使用Java8中新增的-parameters参数编译选项,可以将方法参数的名称保存到class文件中。这样在反射时就可以通过getParameterName方法获取到参数名了。

Method method = Demo.class.getMethod("test", String.class, int.class);
Parameter[] parameters = method.getParameters();
for (Parameter parameter : parameters) {
    String name = parameter.getName();
    System.out.println(name);
}

如果没有使用-parameters参数编译选项,则getParameterName方法将返回null。

3、获取参数类型

Parameter类提供了两种方法用于获取参数类型:getType和getParameterizedType。

getType用于获取普通类型的参数,而getParameterizedType用于获取泛型类型参数。

public void test(List<String> list, T t) {}

获取List和T类型参数的方式如下:

Method method = Demo.class.getMethod("test", List.class, Object.class);
Parameter[] parameters = method.getParameters();
for (Parameter parameter : parameters) {
    System.out.println(parameter.getType()); // 输出:java.util.List, class java.lang.Object
    System.out.println(parameter.getParameterizedType()); // 输出:java.util.List<java.lang.String>, T
}
二、Executable接口

Executable是Method和Constructor的父接口,它定义了一些方法用于访问方法/构造方法的参数信息。

1、获取全部参数信息

可以通过getParameters方法一次性获取全部参数信息。

Method method = Demo.class.getMethod("test", String.class, int.class);
Parameter[] parameters = ((Executable) method).getParameters();
for (Parameter parameter : parameters) {
    System.out.println(parameter.getName()); // 打印参数名
    System.out.println(parameter.getType()); // 打印参数类型
}
2、获取参数的Annotation信息

使用getParameterAnnotations()getParameterAnnotation(int parameter)两个方法可以获取参数的Annotation信息

Method method = Demo.class.getMethod("test", String.class, @MyAnnotation int.class);
Parameter[] parameters = ((Executable) method).getParameters();

//遍历参数的Annotation信息
for (Parameter parameter : parameters) {
    Annotation[] annotations = parameter.getAnnotations();
    for (Annotation annotation : annotations) {
        System.out.println(annotation.annotationType().getSimpleName());
    }

    //获取某个参数的Annotation信息
    MyAnnotation myAnnotation = parameter.getAnnotation(MyAnnotation.class);
    if (myAnnotation != null) {
        System.out.println("value: " + myAnnotation.value());
    }
}
3、获取参数的命名

getMethod()或getConstructors()等方法在指定方法时可以同时获取参数名:

class Demo{
    public String test(String aaa, int bbb) {
        return "Return Value";
    }
}
Method method = Demo.class.getMethod("test", String.class, int.class);

for (Parameter parameter : method.getParameters()) {
    System.out.println("parameter name : " + parameter.getName());
}

当参数名未保存在class文件中时,getName()会按"arg0"、"arg1"的格式进行返回。

为了保存参数名,可以使用编译器的“-parameters”选项。

三、总结

Java8中新增加的Parameter类和Executable接口为反射操作提供了更加方便的工具和接口。

通过Parameter类,程序员可以直接获得方法参数的信息,例如参数名和参数类型,而不需要通过解析方法的字符串描述。

通过Executable接口,程序员可以更加方便地访问方法/构造方法的参数信息,例如Annotation信息和参数名称。