【发布时间】:2015-08-08 20:47:04
【问题描述】:
我正在尝试从方法中获取注释,但遇到了一些麻烦。我正在做的是使用 URLClassLoader 加载一个 jar 文件,然后我正在使用反射和 Method.getAnnotation 检查该 jar 中类中方法的注释。
我遇到的问题是 Method.getAnnotation 将返回始终返回 null,即使注释存在(我们可以使用 Method.getAnnotations 看到)。我已经在没有使用 URLClassLoader 加载的类上对相同的注释类型测试了相同的过程,它工作正常。
更深入的调查表明 instance.annotationType() 和 MyAnnotation.class 的规范名称是相同的。但是 instance.annotationType().equals(MyAnnotation.class) 返回 false。然而,实例本身是一个代理 (com.sun.proxy)。
有没有办法在没有大量反射的情况下获取注释和注释的字段?
instance.annotationType().getMethod("value").invoke(instance)
以上内容可以在该领域工作,并通过对规范名称的字符串比较迭代 Method.getAnnotations 的结果可以获得注释,但肯定有更好的方法吗?
还有教育价值,是什么原因造成的?我的猜测是,这是因为系统类加载器加载的注解的类与 URL 类加载器加载的注解的类在某种程度上不同。
【问题讨论】:
-
我同意你的猜测。存在两种类型的 MyAnnotation。要解决此问题,请确保使用相同的类加载器加载带注释的类和注释。如果您的自定义类加载器使用当前的类加载器作为父类,也许会有所帮助。
-
@CoronA 自定义类加载器确实使用当前类加载器作为父类。我不知道如何确保它们使用相同的加载器加载,我需要更多关于 JVM 内部和这些类型事物的生命周期的知识。
-
您可能可以访问您的自定义类加载器。您可以调用
getAnnotation(customClassLoader.load("MyAnnotation"))(使用完整的类名)而不是调用getAnnotation(MyAnnotation.class)。确保在加载此类之前未引用 MyAnnotation。 -
试过了,打字有问题。 load 需要一个 Class
,但我不知道如何让 T 成为 MyAnnotation。 -
@kag0 如果您显示类加载器代码或它是如何创建的,那么有人可能会帮助修复父委托。否则,尝试使用
Annotation.class.cast(customClassLoader.loadClass("MyAnnotation"))安抚javac。
标签: java reflection annotations classloader proxy-classes