我的初步问题与this one完全相同;也就是说,为什么这个接口有一个运行时保留策略。
但是接受的答案根本不能让我满意,原因有两个:
@Documented
的事实(我相信)与它无关(尽管为什么@Documented
有一个运行时保留策略对我来说也是个谜); Comparable
作为答案提及,但Runnable
等),这并不妨碍它们被用作“替代“(例如,如果您所做的只是对DirectoryStream.Filter
进行过滤,则可以完美地使用Predicate
替代Path
。但是,它有这种保留。这意味着它必须以某种方式影响JVM行为。怎么样?
答案 0 :(得分:4)
我在core-libs-dev邮件列表中找到thread,其中讨论了@FunctionalInterface
注释的保留。这里提到的要点是允许第三方工具使用此信息进行代码分析/验证,并允许非Java JVM语言将其lambda正确映射到功能接口。一些摘录:
Joe Darcy (@FunctionalInterface
的原始提交者):
我们故意让这个注释具有运行时保留功能 允许它在运行时也可以查询各种工具等。
Brian Goetz
语言其他比Java有一个好处,它可以用它来确定接口是否适合传递给SAM转换机制。 JDK对lambda转换的支持也可用于其他语言。
似乎它并没有被JVM本身使用,它只是第三方工具的另一种可能性。使注释运行时可见并不是一个很大的成本,所以似乎没有强烈的理由不做这个。
答案 1 :(得分:1)
保留策略运行时注释的唯一要求是
注释将由编译器记录在类文件中,并在运行时由VM保留,因此可以反射性地读取它们。 (https://docs.oracle.com/javase/7/docs/api/java/lang/annotation/RetentionPolicy.html#RUNTIME)
现在这会对运行时行为产生一些影响,因为类加载器必须加载这些annoations,并且VM必须将这些注释保留在内存中以便反射访问(例如,通过第三方库)。
然而,VM不需要对此类注释采取行动。