Java @functionanterface如何影响JVM';什么是运行时行为?
我最初的问题完全是重复的;也就是说,为什么该接口具有运行时保留策略 但我完全不满意被接受的答案,原因有两个:Java @functionanterface如何影响JVM';什么是运行时行为?,java,annotations,java-8,Java,Annotations,Java 8,我最初的问题完全是重复的;也就是说,为什么该接口具有运行时保留策略 但我完全不满意被接受的答案,原因有两个: 这个接口是@Documented的事实(我相信)与此无关(尽管@Documented为什么有运行时保留策略对我来说也是个谜) 尽管在Java 8之前的Java中存在许多“可能”的功能接口(如答案所述,还有Runnable等),但这并不妨碍它们被用作“替代品”(例如,如果只需在路径上进行筛选,则可以很好地使用DirectoryStream.Filter作为谓词的替代品) 但是,它仍然有
- 这个接口是
的事实(我相信)与此无关(尽管@Documented
为什么有运行时保留策略对我来说也是个谜)李>@Documented
- 尽管在Java 8之前的Java中存在许多“可能”的功能接口(如答案所述,还有
等),但这并不妨碍它们被用作“替代品”(例如,如果只需在Runnable
上进行筛选,则可以很好地使用路径
作为DirectoryStream.Filter
的替代品)谓词
但是,它仍然有这种保留。这意味着它必须以某种方式影响JVM的行为。如何影响?对带有保留策略运行时的注释的唯一要求是 注释将由编译器记录在类文件中,并在运行时由VM保留,因此可以反射地读取它们。() 现在,这对运行时行为有一些影响,因为类加载器必须加载这些注释,并且VM必须将这些注释保留在内存中以进行反射访问(例如由第三方库进行) 但是,不要求VM对此类注释进行操作。我发现了核心libs dev邮件列表,其中讨论了
@functional interface
注释的保留。这里提到的要点是允许第三方工具使用此信息进行代码分析/验证,并允许非Java JVM语言使其lambda正确映射到功能接口。一些摘录:
乔·达西(功能界面的原始提交人):
我们有意使此批注具有运行时保留
允许在运行时将其查询到各种工具等
布莱恩·戈茨
Java以外的语言有一个好处,可以将其用作确定接口是否适合传递给SAM转换机制的方法。其他语言也可以使用JDK对lambda转换的支持
因此,JVM本身似乎没有使用它,这只是第三方工具的一种附加可能性。使注释运行时可见的成本不高,因此似乎没有充分的理由不这样做。这是一个非常奇怪的结论,即保留策略
运行时
意味着它对JV有影响因为您已经知道可以用lambda表达式实现函数接口,即使它们没有注释(我想您知道),完全可选的东西应该在JVM行为上有什么样的变化?@Holger这正是我想知道的,因此我提出了这个问题。但最终,它似乎没有什么区别……实际上,使注释运行时可见可以降低成本。字节码表示是相同的,只有属性名从Ru更改ntimeInvisibleAnnotations
到RuntimeVisibleAnnotations
,因此每个类文件至少要保存两个字节。考虑到您可能有其他运行时可见的注释,而不可见的注释非常少见,保存可能更高,因为这样可以避免在类文件中同时存在两个属性名。@Holg呃,虽然它可能会稍微减小类文件的大小,但是当您请求class.getAnnotations()时,它会增加运行时的成本,因为运行时可见的注释会变成java对象
。如果您提出请求,则有关@functionanterface
的信息将一直保留在内存中,直到类被卸载,即使您实际查找了其他注释。但是,考虑到加载的类中只有一小部分使用@functionanterface
进行注释,这并不是很大的成本。