我试图从方法中获得注释,但我遇到了一些麻烦。我正在做的是使用URLClassLoader加载一个jar文件,然后我使用反射和method . getnotation检查该jar中类中方法的注释。
我遇到的问题是方法。getAnnotation将总是返回null,即使注释在那里(我们可以使用method .getAnnotation看到)。我已经在相同的注释类型上对未加载URLClassLoader的类测试了相同的过程,它工作得很好。
更深入的调查显示,instance.annotationType()和myannotationclass的规范名称是相同的。然而instance.annotationType().equals(myannotationclass)返回false。然而,实例本身是一个代理(com.sun.proxy)。
是否有一种方法可以在没有大量反射的情况下获得注释和注释的字段?
instance.annotationType().getMethod("value").invoke(instance)
上面的代码可以得到字段,并遍历Method的结果。getAnnotations对规范名称进行字符串比较可以得到注释,但肯定有更好的方法吗?
还有教育价值,这是什么原因?我的猜测是,这是因为系统类装入器装入的注释的类与URL类装入器装入的注释的类在某种程度上不同。
一个简单的解决方案如下:
代替AccessibleObject。使用
private static Annotation getAnnotation(AccessibleObject object, Class annotationClass){
for(Annotation a : object.getAnnotations()){
if(a.annotationType().getCanonicalName().equals(annotationClass.getCanonicalName()))
return a;
}
return null;
}
用
代替myannotationvalue ()private static Object getAnnotationFieldWithReflection(Annotation annotation, String fieldName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
return annotation.annotationType().getMethod(fieldName).invoke(annotation);
}
我遇到了同样的问题,而且很难调试。对此,我的解决方案是从类实例引用中使用相同的类加载器。
例如,给定一个Jar文件,您想要加载在其中找到的类,您可以从包中引用一个类实例并获得它使用的类加载器:
URLClassLoader
.newInstance(arrayOf(URL("jar:file:${it.path}!/")), AGivenClass::class.java.classLoader)
然后我可以成功地收集感兴趣的注释。
这是Kotlin中的一个例子,因为同样的问题也发生在那里,所以我希望它能对未来的读者有所帮助。
我认为ClassLoader#loadClass(name, true)
是需要的,这实际上将完全加载类(resolve=true)。注意,这也初始化了类。