【发布时间】:2018-01-25 15:32:33
【问题描述】:
Java (1.8+) 有一个 @FunctionalInterface 注释,它(基本上)建议您可以将方法引用而不是接口实现传递给另一个方法调用。我今天玩的有用的是:
DateTimeFormatter.parse(String, TemporalQuery<T>)
这很好,因为它可以让您告诉格式化程序将什么样的结果交还给您。 javadoc 甚至给了你一个很好的例子:
The query is typically a method reference to a from(TemporalAccessor) method. For example:
LocalDateTime dt = parser.parse(str, LocalDateTime::from);
当我了解@FunctionalInterface 是什么以及它的含义后,我开始想知道 API 的使用者是如何弄清楚他们可以实际使用什么来代替它的。上面的示例告诉您可以使用什么,如果您跟踪 java.time 包,您可以找到其他可以使用的方法引用。但是,API 的任何贡献者都需要通读整个 javadoc,以确保他们不会破坏其他地方提到的任何隐式契约(当然他们应该这样做,尤其是对于 JDK,但这不是 javadoc 的目的!)
所以.. 如果此 API 的贡献者要更改 LocalDateTime::from 的签名,则没有编译时检查表明此方法不再符合“TemporalQuery”的 FuncitonalInterface。这显然会破坏 API 的任何消费者,他们可以更改代码以使用显式 lambda。我确实理解它不需要,但如果有一个类似于可选的“@Override”注释的注释可用,那么它将提供一些编译时检查以及自省/反思以发现可用方法引用的可能性。
例如
@ConformsTo(TemporalQuery.class)
public static LocalDateTime from(TemporalAccessor temporal)
然后,还可以通过自省找到可用于功能接口的任何其他方法引用。
所以,需要明确的是,我理解这不是必需的,但确实认为不将其作为可选注释包含在内似乎是一种疏忽。这可能/不应该存在有什么特别的原因吗?
【问题讨论】:
-
请注意,
@FunctionalInterface不允许你传递一个方法引用,它表明接口是意味着以这种方式使用。即使接口上缺少该注释,您也可以传递方法引用。 -
是的,我确实希望使用“(基本上)”可以让我摆脱语义,但你说得对,我应该更清楚地说明:)
-
您可以在代码中添加
static { if(false) { TemporalQuery verify = LocalDateTime::from; } }...
标签: java lambda api-design functional-interface