通过反射获取注解的值(不知道具体的注解类型)

发布于 2025-01-16 18:58:41 字数 1449 浏览 0 评论 0原文

我有以下类:

public final class SomeClass {
    
    @Signature("some info")
    public void someMethod() {

    }

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ ElementType.METHOD })
    @Inherited
    private @interface Signature {

        String value();
    }    
}

该类不在我的源代码中,也不在依赖项中,它是在运行时从资源文件即时编译的。这意味着,符号 Signature.class (以及 SomeClass.class)在我的类加载器中不存在,并且在编译时永远不会存在,所以我不能做简单的事情:

Signature signature = method.getAnnotation(Signature.class);
signature.value();

我想检索在运行时分配给注释 @Signature 的值,但我无法做到。 我所知道的是,该方法只有一个注释(@Signature 注释),并且该注释始终有一个参数value,但这就是我所知道的。

这是我的(原始)尝试:

Class<?> compiledClass = compiler.compile(classSourceCode); //this properly return the class instance
for (Method method : compiledClass.getDeclaredMethods()) {
    for (Annotation annotation : method.getAnnotations()) {
        Class<? extends Annotation> realType = annotation.annotationType();
        for (Method annotationMethod : realType.getDeclaredMethods()) {
            System.out.println(annotationMethod.invoke(annotation)); //<-- THIS FAILS
        }
    }
}     

我在运行时遇到的失败是:

java.lang.IllegalAccessException:类 SomeClass 无法使用修饰符“public abstract”访问接口 SomeClass$Signature 的成员

我得到的方法是方法value()

我怎样才能做到这一点?

I have the following class:

public final class SomeClass {
    
    @Signature("some info")
    public void someMethod() {

    }

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ ElementType.METHOD })
    @Inherited
    private @interface Signature {

        String value();
    }    
}

This class is not in my source code nor in a dependency, it's compiled from a resource file on-the-fly at runtime. That means, the symbol Signature.class (as well as SomeClass.class) do not exist in my class loader and will never do at compile time, so I can't do the easy:

Signature signature = method.getAnnotation(Signature.class);
signature.value();

I would like to retrieve the value that is assigned to the annotation @Signature at runtime, but I'm being unable to.
All I know is that the method will only have one annotation (the @Signature annotation) and that this annotation will always have one parameter value, but that's all I know.

This is my (raw) attempt:

Class<?> compiledClass = compiler.compile(classSourceCode); //this properly return the class instance
for (Method method : compiledClass.getDeclaredMethods()) {
    for (Annotation annotation : method.getAnnotations()) {
        Class<? extends Annotation> realType = annotation.annotationType();
        for (Method annotationMethod : realType.getDeclaredMethods()) {
            System.out.println(annotationMethod.invoke(annotation)); //<-- THIS FAILS
        }
    }
}     

The failure that I get at runtime is:

java.lang.IllegalAccessException: class SomeClass cannot access a member of interface SomeClass$Signature with modifiers "public abstract"

The method that I get is the method value().

How can I do that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文