当类返回Lambdas时,为什么reflection不起作用
我遇到了一个有点奇怪的行为。 我使用注释来标记具有特定目的的某些类,然后我使用org.reflections库来查找具有特定注释的所有类。 但是,当一个类实现一个返回lambda函数的方法时,reflection将不再找到带注释的类。 class级的签名没有变化。
注释示例:
@Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { String someValue(); }
使用注释(编辑 – 添加了BaseClass):
public class BaseClass { public Consumer doSomething(){ return null;} } @MyAnnotation(someValue = "a") public class FooBar extends BaseClass { @Override public Consumer doSomething() { return null; } } @MyAnnotation(someValue = "bazbar") public class BarClass extends BaseClass { @Override public Consumer doSomething(){ return (x) -> {}; } }
找到注释
private static final Reflections reflections = new Reflections("com.mypackage"); Set<Class> clazzes = reflections.getTypesAnnotatedWith(MyAnnotation.class);
现在 – 集合’clazzes’只包含1个单独的类 ,即FooBar类。 如果我从BazBar类中删除lambda返回值也会显示,但只要该类中的一个方法返回一个lambda,reflection就不会起作用。
我迷路了,有什么想法吗?
从问题列表看,这个库似乎还不适合Java 8function。 我认为你最好的办法是报告这个问题并提供修复。
您可以在没有任何第三方代码的情况下执行查找,如下所示:
private static Set> getAnnotated( Class> context, Class anno) throws IOException, URISyntaxException { URI clURI = context.getResource(context.getSimpleName()+".class").toURI(); if(!clURI.getScheme().equals("file")) try { FileSystems.getFileSystem(clURI); } catch(FileSystemNotFoundException ex) { FileSystems.newFileSystem(clURI, Collections.emptyMap()); } String pkg=context.getPackage().getName(); return Files.list(Paths.get(clURI).getParent()) .map(p->p.getFileName().toString()) .filter(s->s.endsWith(".class")) .map(s->s.substring(0, s.length()-6)) .map(s-> { try { return context.getClassLoader().loadClass(pkg+'.'+s); } catch(ClassNotFoundException ex) { return null; } }) .filter(c -> c!=null && c.isAnnotationPresent(anno)) .collect(Collectors.toSet()); }
Path
优于旧File
的优点在于它抽象文件系统(存储),因此即使Class
存储在jar文件(或存在FileSystemProvider
任何其他类存储中),也可用于列出包成员)。
你可以用它作为
Set> clazzes = getAnnotated(context, MyAnnotation.class);
其中context
是要为其获取带注释类的包中的Class
。