Java 8 为我们提供了许多有趣的方法来使用函数式接口以及新的注释:@功能接口 http://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html。它的工作是告诉编译器如果我们不遵守函数式接口的规则就向我们大喊大叫(请只需要重写一个抽象方法)。
有java.util.function包中的43个接口 https://stackoverflow.com/questions/27743315/a-summary-of-the-parameters-and-return-type-of-functional-interfaces-in-the-pack/28162720#28162720与此注释。搜索jdk.1.8.0/src@FunctionalInterface
仅出现 57 个点击。为什么可以添加其他接口(例如 AutoCloseable)@FunctionalInterface
还失踪吗?
里面有一点模糊的暗示注释文档 http://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html:
“用于指示接口类型声明的信息注释类型intended成为一个功能性接口”
有什么充分的理由不intend我设计的一个接口(可能只是一个功能性接口)不能用作一个接口?除了没有意识到可以添加它之外,将其省略是否还表明有什么?
向任何已发布的接口添加抽象方法是否不会让任何实现它的人陷入困境,无论是否功能正常?假设他们只是懒得去追捕他们,我感到愤世嫉俗,但还有什么其他解释呢?
Update: 看完之后“‘可比较’应该是‘功能性接口’吗?” https://stackoverflow.com/questions/25222575/should-comparablet-be-a-functional-interface我发现我仍然有一些挥之不去的问题。当单一方法接口和功能接口在结构上相同时,还有什么不同呢?区别只是名字吗? Comparable 和 Comparator 在语义上非常接近。事实证明它们在结构上是不同的,所以仍然不是最好的例子......
是否存在这样的情况:SMI 在结构上可以很好地用作功能接口,但仍然不鼓励接口名称和方法的语义含义?或者也许是 Javadocs 隐含的契约?
好吧,如果您假设总是给出该意图,那么记录意图的注释将毫无用处。
你命名了这个例子AutoCloseable
这显然是not旨在作为函数实现,因为有Runnable
这对于具有以下功能的函数来说要方便得多()->void
签名。它的目的是一个类实现AutoCloseable
管理通过 lambda 表达式实现的匿名类无法管理的外部资源。
一个更清楚的例子是Comparable
, an interface
不仅不打算作为 lambda 表达式实现,而且也不可能使用 lambda 表达式正确实现它。
未标记的可能原因interface
with @FunctionalInterface
举例来说:
- The
interface
具有编程语言语义,例如AutoClosable
or Iterable
(对于您自己的界面来说,这种情况不太可能发生)
- 预计不会
interface
具有任意实现和/或比实际实现更多的标识符,例如java.net.ProtocolFamily
, or java.lang.reflect.GenericArrayType
(请注意,后者还将继承default
实施getTypeName()
对于 lambda 实现来说毫无用处,因为依赖toString()
)
-
此类事例interface
应该有一个身份,例如java.net.ProtocolFamily
, java.nio.file.WatchEvent.Modifier
等等。请注意,这些通常由enum
另一个例子是java.time.chrono.Era
恰好只有一个abstract
方法但是它的规格 http://docs.oracle.com/javase/8/docs/api/java/time/chrono/Era.html说“实例Era
可以使用以下方法进行比较==
操作员。”
- The
interface
旨在改变操作的行为,该操作的实现interface
不继承/实现其他任何东西都是没有意义的,例如java.rmi.server.Unreferenced
- 它是类的常见操作的抽象,它应该不仅仅具有这些操作,例如
java.io.Closeable
, java.io.Flushable
, java.lang.Readable
- 预期的继承是合约的一部分,并禁止 lambda 表达式实现,例如在
java.awt
: ActiveEvent
应由一个AWTEvent
, PrinterGraphics
by a Graphics
,同样适用于java.awt.print.PrinterGraphics
(嘿,两个interface
s 表示完全相同的事情......),而javax.print.FlavorException
应由一个javax.print.PrintException
子类
- 不知道各种事件监听接口是不是没有标注
@FunctionalInterface
为了与其他不能是函数式接口的多方法事件监听器对称,但实际上事件监听器是 lambda 表达式的良好候选者。如果您想稍后删除侦听器,则必须存储实例,但这与例如没有什么不同。内部类监听器实现。
-
库维护者拥有一个包含 200 多种候选类型的大型代码库,但没有足够的资源来讨论每个类型interface
是否应该对其进行注释,因此重点关注在功能上下文中使用的主要候选者。我确信,例如java.io.ObjectInputValidation
, java.lang.reflect.InvocationHandler
, juc RejectedExecutionHandler
& ThreadFactory
不会那么糟糕@FunctionalInterface
但我不知道是否,例如java.security.spec.ECField
是一个好的候选人。图书馆越通用,图书馆的用户就越有可能回答特定问题interface
他们感兴趣,但坚持让图书馆维护者回答是不公平的all接口。
在这种情况下,看到一个@FunctionalInterface
作为一条消息interface
绝对是为了与 lambda 表达式一起使用,而不是将注释的缺失视为不打算以这种方式使用的指示符。这就像编译器处理它一样,您可以实现每个抽象方法interface
使用 lambda 表达式,但是当注释存在时它会ensure你可以使用这个interface
这样。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)