查找包括lambda表达式在内的接口所有实现

4
我有一个单元测试,它会搜索我的项目并找到特定接口的所有实现。然后对于每个内部类的实现,我断言它不会捕获外部类。
我使用Reflections库来完成这个任务,它确实起作用了,但现在我需要测试另一个接口,其中许多实现是lambda表达式。不幸的是,Reflections无法找到接口的lambda实现。
是否有其他解决方案可以与lambda一起使用?

这里不接受关于图书馆推荐的请求。 - John Bollinger
2
你可以使用像ASM这样的字节码处理库编写一个工具,以查找所有lambda创建位置,但确定它们是否捕获了外部的this实例是棘手的,因为该类型的捕获引用的存在并不一定是this;它也可能是故意捕获的相同类型的变量。此外,我想你只关心意外捕获,所以像this::method这样的显式构造不应计入... - Holger
1个回答

4
Reflections无法找到接口的lambda实现。是否有其他解决方案可以与lambda一起使用?
没有可靠的方法来使用反射识别功能接口的实例,而且看起来永远不会有。请参阅对引入编译器选项以使用签名属性存储关于lambda表达式的通用类型信息的openjdk请求的回复:
我知道人们为什么希望反射在lambda实例上工作,但这不是反射的工作方式-反射反映类,而不是实例。当前的翻译策略恰好是一种,如果有了这个属性,它将使反射“意外地工作”,以提供通用信息,但这将会改变,在这一点上,任何基于反射的策略都会崩溃(在这一点上,人们指责打破他们本来就不应该工作的代码)。

同样地,可以看到这些评论(也来自Brian Goetz)在这个SO帖子中为什么Java 8 lambda使用invokedynamic调用?

运行时实现可以动态选择一种策略来评估lambda表达式。 运行时实现的选择被隐藏在标准化的(即平台规范的)lambda构造API后面,以便静态编译器可以发出对此API的调用,而JRE实现可以选择其首选的实现策略

最重要的是,您无法知道您的lambda表达式将如何在运行时处理。


2
这是没有抓住重点。引用的邮件是关于希望获取lambda实例的通用类型信息,与此问题无关。而引用的问答只是说明您无法定位接口实现类,因为它是JRE特定的,但这并不排除查找“invokedynamic”指令,这已经告诉您将要实现哪个接口以及它必须捕获哪些值。您不需要知道它是如何做到的... - Holger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接