最近,我开始了一个新的项目,其中具有单个抽象方法的所有接口都用@functionalinterface
来代替。我经常看到有人在界面中添加另一个抽象方法后删除注释。我什么时候问过为什么?他们告诉我,公司里有个不在的人让他们那样做。现在我不确定对显然不会与lambdas一起使用的接口进行注释是不是一个好主意。
现在我看到了一个有用的信息,就是人们甚至在服务中也在使用anotation。我就像一个代码:
@FunctionalInterface
public interface SomeService {
void doSomething();
}
每个只提供一个(抽象)方法的接口,即没有实现的接口,都是所谓的函数接口。
明示地或含蓄地。
如果要创建函数接口,注释@functionalinterface
与@override
一样是可选的。
如果您没有注释,它将编译,但它不再是一个功能接口。这对您来说可能是一个bug,因为您的意图是创建一个功能接口。请注意,如果您实际上是在一个需要函数接口的环境中使用该接口,比如lambda,那么当另一个方法添加到该接口时,它显然不会再编译了。
以下是一些例子:
// is a functional interface
interface Foo {
void bar();
}
// is a functional interface
@FunctionalInterface
interface Foo {
void bar();
}
// is not a functional interface
interface Foo {
void bar();
void baz();
}
// does not compile
@FunctionalInterface
interface Foo {
void bar();
void baz();
}
它是向编译器、其他团队成员和你未来的自己表明你的意图。这样,编译器就可以帮助你发现错误,以防你搞砸了。
相反的情况也是如此。如果他们发现你的一个接口只有一个方法,但没有显式注释,他们就会明白这不是用来作为函数接口的,即使它目前是一个。因此,他们不会将它用于lambda,尽管他们可以,因为您可能会在将来的更新中更改它。
您可以在JLS§9.8中了解精确的定义。功能接口:
函数接口是一个只有一个抽象方法(对象的方法除外)的接口,因此表示一个单一的函数契约。这种“单一”方法可能采取多个抽象方法的形式,具有从超接口继承的重写等价签名;在这种情况下,继承的方法在逻辑上表示单个方法。
和JLS§9.6.4.9。@FunctionalInterface:
注释类型FunctionalInterface用于指示接口是功能接口(§9.8)。它有助于早期检测在一个功能接口中出现的或由其继承的不适当的方法声明。
如果接口声明被@FunctionalInterface注释,但实际上不是函数接口,则是编译时错误。
如前所述,@override
标记的工作原理相同,但用于重写方法。因此您也可以在不使用它的情况下重写方法。但如果您使用它时可能出现了一个错误,即您实际上没有重写某些东西,编译器将帮助您立即发现这个问题。
但是为什么一个函数接口应该只有一个抽象方法呢?如果接口有多个抽象方法,为什么这不是函数接口?
我正在重构我的代码,所以我需要做出关于接口或抽象类的决定。我有基类Player和继承基类的类,称为VideoPlayer、MusicPlayer等。基类有抽象方法,没有实现(Play)。那么,最好的方法是什么?将Play放在接口中或将其留在抽象类中。在MusicPlayer中播放与在VideoPlayer中的播放器不同。我是用C#实现的。
现在使用Lambda表达式,为什么Java不能允许以下两个,因为它清楚地区分了这两个:
当我看到Iterable接口源时,它看起来像方法和方法不是抽象的。接口如何具有非抽象方法?还是我在这件事上漏掉了什么?请参阅下面的接口源代码。
问题内容: 考虑一个示例(在Java中编译) 为什么必须将接口“声明”为抽象的?还有其他适用于抽象接口的规则吗? 最后:如果过时了,为什么将它包含在Java中?有抽象接口的历史吗? 问题答案: 为什么必须将接口“声明”为抽象的? 不是。 接口及其方法是隐式的,添加该修饰符没有区别。 还有其他适用于抽象接口的规则吗? 不,适用相同的规则。该方法必须由任何(具体)实现类来实现。 如果抽象已经过时,为什