can*_*nge 16 java functional-programming java-8 functional-interface
Java 8为我们提供了许多有趣的方法来使用功能接口,并为它们添加了一个新的注释:@FunctionalInterface.如果我们不遵守功能接口的规则(只需要一个需要覆盖的抽象方法),它的工作就是告诉编译器对我们大喊大叫.
java.util.function包中有43个接口,带有此批注.搜索jdk.1.8.0/src @FunctionalInterface只能获得57次点击.为什么其他可能添加的接口(如AutoCloseable)@FunctionalInterface仍然缺少它?
注释文档中有一些模糊的提示:
"用于指示接口类型声明旨在成为功能接口的信息性注释类型"
有没有什么好的理由不打算我设计的接口(可能只是一个功能接口)不能用作一个接口?除了没有意识到它可能被添加之外,是否有任何迹象?
是不是将抽象方法添加到任何已发布的接口来阻止实现它的任何人,功能与否?我觉得玩世不恭,假设他们只是懒得去追捕他们,但其他解释是什么?
更新:看过"应该'可比'是一个'功能界面'?" 我发现我仍然有唠叨的问题.当单一方法接口和功能接口在结构上相同时,它们会有什么不同?简单的名称是不同的?Comparable和Comparator在语义上足够接近.事实证明它们在结构上是不同的,但仍然不是最好的例子......
是否有一种情况,SMI在结构上很好用作功能接口,但仍然不鼓励接口名称和方法的语义含义?或者也许是Javadocs隐含的合同?
Hol*_*ger 21
好吧,如果你假设总是给出意图,那么记录意图的注释将毫无用处.
您将该示例命名AutoCloseable为显然不是作为函数实现的,因为Runnable对于具有()->void签名的函数来说更方便.它旨在实现一个类AutoCloseable管理外部资源,通过lambda表达式实现的匿名类不能这样做.
更清楚的例子是Comparable,interface不仅不打算将其实现为lambda表达式,使用lambda表达式也无法正确实现它.
interface与@FunctionalInterface通过例如:interface具有编程语言的语义,如AutoClosable或Iterable(这是不可能发生的为自己的接口)interface具有任意实现和/或更多是标识符而不是实际实现,例如java.net.ProtocolFamily,或者java.lang.reflect.GenericArrayType(注意后者也将继承default对于getTypeName()依赖于lambda实现无用的实现toString())这样做的情况下,interface应该有一个身份,例如java.net.ProtocolFamily,java.nio.file.WatchEvent.Modifier等等.需要注意的是,这些通常由实施enum
另一个例子是java.time.chrono.Era恰好只有一个abstract方法,但其规范说" Era可以使用==运算符对实例进行比较".
interface是为了改变一个操作的其中一个实施的行为interface不继承/实现别的是没有意义的,如java.rmi.server.Unreferencedjava.io.Closeable,java.io.Flushable,java.lang.Readablejava.awt:ActiveEvent应当由执行AWTEvent,PrinterGraphics由Graphics,同样适用于java.awt.print.PrinterGraphics(嘿,双interfaceS表示完全一样的东西......),wheras javax.print.FlavorException应由执行javax.print.PrintException子@FunctionalInterface为与其他多方法事件监听器不对称的对称性,但实际上事件监听器是lambda表达式的良好候选者.如果要在以后删除侦听器,则必须存储实例,但这与实例内部类侦听器没有区别.库维护者拥有一个包含200多种候选类型的大型代码库,而不是讨论每个interface是否应该注释的资源,因此专注于在功能上下文中使用的主要候选者.我敢肯定,例如java.io.ObjectInputValidation,java.lang.reflect.InvocationHandlerjuc RejectedExecutionHandler&ThreadFactory并不会坏,@FunctionalInterface但我不知道是否,例如,java.security.spec.ECField成为一个好的候选人.库越普遍,库的用户就越有可能针对interface他们感兴趣的特定问题回答这个问题,但坚持让库维护人员为所有接口回答它是不公平的.
在这种情况下,更有意义的是将a @FunctionalInterface作为消息的interface存在明确地与lambda表达式一起使用,而不是将注释的缺失视为指示它不打算以这种方式使用.这与编译器处理它完全一样,您可以interface使用lambda表达式实现每个抽象方法,但是当注释存在时,它将确保您可以interface以这种方式使用它.