4.4 @FunctionalInterface

2.4节虽已讨论过函数接口定义的标准,但未提及@FunctionalInterface注释。事实上,每个用作函数接口的接口都应该添加这个注释。

这究竟是什么意思呢?Java中有一些接口,虽然只含一个方法,但并不是为了使用Lambda表达式来实现的。比如,有些对象内部可能保存着某种状态,使用带有一个方法的接口可能纯属巧合。java.lang.Comparablejava.io.Closeable就属于这样的情况。

如果一个类是可比较的,就意味着在该类的实例之间存在某种顺序,比如字符串中的字母顺序。人们通常不会认为函数是可比较的,如果一个东西既没有属性也没有状态,拿什么比较呢?

一个可关闭的对象必须持有某种打开的资源,比如一个需要关闭的文件句柄。同样,该接口也不能是一个纯函数,因为关闭资源是更改状态的另一种形式。

CloseableComparable接口不同,为了提高Stream对象可操作性而引入的各种新接口,都需要有Lambda表达式可以实现它。它们存在的意义在于将代码块作为数据打包起来。因此,它们都添加了@FunctionalInterface注释。

该注释会强制javac检查一个接口是否符合函数接口的标准。如果该注释添加给一个枚举类型、类或另一个注释,或者接口包含不止一个抽象方法,javac就会报错。重构代码时,使用它能很容易发现问题。