当类返回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