每个具有单个抽象方法的接口都应该是功能接口吗?
Every interface with a single abstract method should be a functional interface?
最近我开始了一个新项目,其中所有具有单个抽象方法的接口都用 @FunctionalInterface
注释。我经常看到人们在接口中添加另一个抽象方法后删除注释。我什么时候问过为什么?他们告诉我,一个不在公司的人告诉他们那样做。现在我不确定注释显然不会与 lambda 一起使用的接口是否是个好主意。
现在我看到一条有用的信息,就是人们甚至在服务中的服务中都在使用注释。我只是看起来像这样的代码:
@FunctionalInterface
public interface SomeService {
void doSomething();
}
说明
每个只提供一个(抽象)方法的接口,即没有实现的接口,都是所谓的功能接口。
明确或隐含。
注解 @FunctionalInterface
与 @Override
一样,如果您想创建函数式接口,则为可选注解。
因此,如果您声明了一个接口 @FunctionalInterface
,但它实际上有不止一个这样的方法,编译器会帮助您并防止编译出错。告诉你,你违背了自己的本意。
如果你没有注释,它会编译,但它不再是一个功能接口。这对您来说可能是一个错误,因为您的意图是创建一个功能界面。请注意,如果您实际上是在实际需要功能接口的环境中使用该接口,例如 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();
}
使用
是为了让编译器、其他团队成员和未来的自己明白你的意图。这样,编译器可以帮助您发现错误,以防您搞砸了。
另一种情况可能是您在团队中工作并设计界面。如果您没有通过注释或 comment/documentation 将此接口明确标记为功能接口,则其他团队成员可能不知道您的意图并向其添加更多方法。
如果您是库设计者,即编写供其他外部人员使用的代码,这一点尤其重要。如果您标记您的界面 @FunctionalInterface
,这是对他们的承诺,您打算保持它的状态。因此,他们可以安全地将其用于 lambda 等。不用担心一旦您将更新发送到您的库,他们的代码就会崩溃。
反之亦然。如果他们发现你的接口只有一个方法,但没有明确注释,他们会明白这并不意味着用作功能接口,尽管它目前是一个。因此,他们不会将它用于 lambda,尽管他们可以,因为您可能会在以后的更新中更改它。
详情
您可以在 JLS§9.8. Functional Interfaces:
中阅读准确的定义
A functional interface is an interface that has just one abstract method (aside from the methods of Object), and thus represents a single function contract. This "single" method may take the form of multiple abstract methods with override-equivalent signatures inherited from superinterfaces; in this case, the inherited methods logically represent a single method.
和JLS§9.6.4.9. @FunctionalInterface:
The annotation type FunctionalInterface is used to indicate that an interface is meant to be a functional interface (§9.8). It facilitates early detection of inappropriate method declarations appearing in or inherited by an interface that is meant to be functional.
It is a compile-time error if an interface declaration is annotated with @FunctionalInterface but is not, in fact, a functional interface.
Because some interfaces are functional incidentally, it is not necessary or desirable that all declarations of functional interfaces be annotated with @FunctionalInterface.
最后一段特别重要。 IE。您可能偶然创建了一个功能界面,并计划稍后向其添加更多内容。所以人们不应该误会这一点并将其与 lambda 一起使用,否则当您添加更多方法时,他们的代码稍后会崩溃。
备注
如前所述,@Override
标签的作用相同,但用于覆盖方法。所以你也可以在没有它的情况下覆盖方法。但是如果你使用它并且可能打错了字,即你实际上并没有覆盖某些东西,编译器会帮助你立即发现这个问题。
I'm not sure if it's a good idea to annotate interfaces that obviously
will not be used with lambdas
不是。充其量,这是浪费时间。最坏的情况是,它具有误导性。
[Use to indicate that the type] is intended to be a functional interface
如果您说它将 "obviously not" 在 lambda 中使用,那么使用标记您 do 期望使用明显矛盾的注释。
最近我开始了一个新项目,其中所有具有单个抽象方法的接口都用 @FunctionalInterface
注释。我经常看到人们在接口中添加另一个抽象方法后删除注释。我什么时候问过为什么?他们告诉我,一个不在公司的人告诉他们那样做。现在我不确定注释显然不会与 lambda 一起使用的接口是否是个好主意。
现在我看到一条有用的信息,就是人们甚至在服务中的服务中都在使用注释。我只是看起来像这样的代码:
@FunctionalInterface
public interface SomeService {
void doSomething();
}
说明
每个只提供一个(抽象)方法的接口,即没有实现的接口,都是所谓的功能接口。
明确或隐含。
注解 @FunctionalInterface
与 @Override
一样,如果您想创建函数式接口,则为可选注解。
因此,如果您声明了一个接口 @FunctionalInterface
,但它实际上有不止一个这样的方法,编译器会帮助您并防止编译出错。告诉你,你违背了自己的本意。
如果你没有注释,它会编译,但它不再是一个功能接口。这对您来说可能是一个错误,因为您的意图是创建一个功能界面。请注意,如果您实际上是在实际需要功能接口的环境中使用该接口,例如 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();
}
使用
是为了让编译器、其他团队成员和未来的自己明白你的意图。这样,编译器可以帮助您发现错误,以防您搞砸了。
另一种情况可能是您在团队中工作并设计界面。如果您没有通过注释或 comment/documentation 将此接口明确标记为功能接口,则其他团队成员可能不知道您的意图并向其添加更多方法。
如果您是库设计者,即编写供其他外部人员使用的代码,这一点尤其重要。如果您标记您的界面 @FunctionalInterface
,这是对他们的承诺,您打算保持它的状态。因此,他们可以安全地将其用于 lambda 等。不用担心一旦您将更新发送到您的库,他们的代码就会崩溃。
反之亦然。如果他们发现你的接口只有一个方法,但没有明确注释,他们会明白这并不意味着用作功能接口,尽管它目前是一个。因此,他们不会将它用于 lambda,尽管他们可以,因为您可能会在以后的更新中更改它。
详情
您可以在 JLS§9.8. Functional Interfaces:
中阅读准确的定义A functional interface is an interface that has just one abstract method (aside from the methods of Object), and thus represents a single function contract. This "single" method may take the form of multiple abstract methods with override-equivalent signatures inherited from superinterfaces; in this case, the inherited methods logically represent a single method.
和JLS§9.6.4.9. @FunctionalInterface:
The annotation type FunctionalInterface is used to indicate that an interface is meant to be a functional interface (§9.8). It facilitates early detection of inappropriate method declarations appearing in or inherited by an interface that is meant to be functional.
It is a compile-time error if an interface declaration is annotated with @FunctionalInterface but is not, in fact, a functional interface.
Because some interfaces are functional incidentally, it is not necessary or desirable that all declarations of functional interfaces be annotated with @FunctionalInterface.
最后一段特别重要。 IE。您可能偶然创建了一个功能界面,并计划稍后向其添加更多内容。所以人们不应该误会这一点并将其与 lambda 一起使用,否则当您添加更多方法时,他们的代码稍后会崩溃。
备注
如前所述,@Override
标签的作用相同,但用于覆盖方法。所以你也可以在没有它的情况下覆盖方法。但是如果你使用它并且可能打错了字,即你实际上并没有覆盖某些东西,编译器会帮助你立即发现这个问题。
I'm not sure if it's a good idea to annotate interfaces that obviously will not be used with lambdas
不是。充其量,这是浪费时间。最坏的情况是,它具有误导性。
[Use to indicate that the type] is intended to be a functional interface
如果您说它将 "obviously not" 在 lambda 中使用,那么使用标记您 do 期望使用明显矛盾的注释。