且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用JDK8和JDK11读取Java批注的值?

更新时间:2021-10-19 15:27:26

您不应依赖通常仅用于调试/记录的toString()实现.

You should not depend on the toString() implementation which is normally for debugging/logging only.

请参见是否可以读取Java中的注释的值?以获取有关如何读取注释的值的更多详细信息.

See Is it possible to read the value of a annotation in java? for more details on how to read the value of an annotation.

更新:

要通过反射来做所有事情,您可以这样做:

To do everything via reflection, you can so something like this:

import org.springframework.transaction.annotation.Transactional;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;

public class AnnotationTest {
    public static void main(String[] args) throws IllegalAccessException, InvocationTargetException {
        Method[] methods = AnnotationTest.class.getMethods();
        System.out.println("methods = " + Arrays.toString(methods));
        for (Method method : methods) {
            System.out.println("method = " + method);
            Annotation[] annotations = method.getAnnotations();
            System.out.println("annotations = " + Arrays.toString(annotations));

            for (Annotation annotation : annotations) {
                System.out.println("annotation = " + annotation);

                Class<? extends Annotation> annotationClass = annotation.annotationType();
                System.out.println("annotationClass = " + annotationClass);
                Method[] annotationMethods = annotationClass.getMethods();
                System.out.println("annotation methods = " + Arrays.toString(annotationMethods));
                for (Method annotationMethod : annotationMethods) {
                    if (Modifier.isPublic(annotationMethod.getModifiers())) {
                        String name = annotationMethod.getName();
                        Object o = annotationMethod.invoke(annotation);
                        System.out.println(name + ": " + o);
                    }

                }
            }
        }
    }

    @Transactional("bla")
    public void test() {
    }
}

(我在这里使用了Spring的注释之一,因为那是我在类路径上碰巧的东西)

(I used one of Spring's annotations here since that is what I happen to have on my classpath)

更新(解决方案结束):

@When(value = "I update text {string} with {string}(\\?)")
public static void main(String[] args) {
    Object as[] = { "a", "b" };
    Class c = Sof.class;
    Method[] methods = c.getMethods();
    Method method = null;
    for (Method m : methods) {
        if (m.getName().equals("main")) {
            method = m;
        }
    }
    Annotation stepAnnotation = method.getAnnotation(When.class);
    Class<? extends Annotation> annotationClass = stepAnnotation.annotationType();
    try {
        Method valueMethods = annotationClass.getDeclaredMethod("value");
        if (Modifier.isPublic(valueMethods.getModifiers())) {
            log.info("---> {} " + String.format(valueMethods.invoke(stepAnnotation).toString().replaceAll("\\{\\S+\\}", "{%s}").replace("(\\?)", ""), as),
                    stepAnnotation.annotationType().getSimpleName());
        }
    } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
        e1.printStackTrace();
    }
}