好吧,如果你假设总是有这个意图,那么记录一个意图的注释将是无用的。
您命名的示例显然不打算作为函数实现,因为对于具有签名的函数来说,这更方便。它的目的是让实现的类管理外部资源,而通过 lambda 表达式实现的匿名类不会这样做。AutoCloseableRunnable()->voidAutoCloseable
一个更清晰的例子是,不仅不打算作为lambda表达式实现,而且使用lambda表达式正确实现它是不可能的。Comparableinterface
不用标记的可能原因示例:interface@FunctionalInterface
- 具有编程语言语义,例如 或者(对于您自己的接口,这不太可能发生)
interfaceAutoClosableIterable
- 预计 没有期望具有任意实现和/或比实际实现更多的标识符,例如,或(请注意,后者也会继承一个实现,因为对于lambda实现无用,因为依赖于
interfacejava.net.ProtocolFamilyjava.lang.reflect.GenericArrayTypedefaultgetTypeName()toString())
-
这种情况的实例应具有标识,例如 、 等。请注意,这些通常由interfacejava.net.ProtocolFamilyjava.nio.file.WatchEvent.Modifierenum
另一个例子是碰巧只有一个方法,但它的规范说“可以使用运算符比较的实例”。java.time.chrono.EraabstractEra==
- 旨在改变一个操作的行为,对于该操作,在没有继承/实现任何其他内容的情况下实现没有意义,例如
interfaceinterfacejava.rmi.server.Unreferenced
- 它是类的常见操作的抽象,这些类应该不仅仅是这些操作,例如,,
java.io.Closeablejava.io.Flushablejava.lang.Readable
- 预期的继承是契约的一部分,禁止 lambda 表达式实现,例如:应该由 a 实现,由 a 实现,同样适用于(嘿,两个 s 用于完全相同的东西...),wheras 应该由子类实现
java.awtActiveEventAWTEventPrinterGraphicsGraphicsjava.awt.print.PrinterGraphicsinterfacejavax.print.FlavorExceptionjavax.print.PrintException
- 我不知道各种事件侦听器接口是否没有标记为与其他不能成为功能接口的多方法事件侦听器的对称性,但实际上事件侦听器是lambda表达式的良好候选者。如果你想在以后删除一个监听器,你必须存储实例,但这没有什么不同,例如内部类监听器实现。
@FunctionalInterface
-
库维护者有一个庞大的代码库,其中包含200多种候选类型,并且没有资源来讨论是否应该对其进行注释,因此专注于在功能上下文中使用的主要候选项。我敢肯定,例如,, , juc & 不会很糟糕,但我不知道是否,例如 成为一个好的候选人。库越通用,库的用户就越有可能为他们感兴趣的特定问题回答这个问题,但是坚持让库维护者为所有接口回答这个问题是不公平的。interfacejava.io.ObjectInputValidationjava.lang.reflect.InvocationHandlerRejectedExecutionHandlerThreadFactory@FunctionalInterfacejava.security.spec.ECFieldinterface
在这种情况下,将 a 的存在视为一条消息,即 a 肯定打算与 lambda 表达式一起使用,而不是将缺少注释视为不打算以这种方式使用的指示器更有意义。这与编译器处理它完全一样,您可以使用lambda表达式实现每个抽象方法,但是当注释存在时,它将确保您可以以这种方式使用它。@FunctionalInterfaceinterfaceinterfaceinterface