如果我们只有一个抽象方法的接口,它默认是功能接口。任何人都可以解释@FunctionalInterface注释带来的额外优势吗?
我知道如果我们添加@FunctionalAnnotation,它将不允许有人在界面中添加另一个抽象方法,因为它会产生编译错误,但我的观点是即使你不使用@FucntionalInterface注释,那么另外,如果有人会添加另一个抽象方法,它会破坏代码中所有现有的lambda表达式,编译器会抱怨。
例如:
如果我有以下界面:
public interface User {
Integer fetchData(Integer userId);
}
以下实施:
public class UserImpl implements User{
@Override
public Integer fetchData(Integer userId) {
return 1;
}
}
以及以下用法:
公共类TestFunctionalInterface {
public static void main(String[] args) {
User user = a -> a*2;
System.out.println("FetchedData:"+user.fetchData(2));
}
}
现在,如果我尝试在界面中添加另一种方法,如下所示:
public interface User {
Integer fetchData(Integer userId);
Integer fetchLoginDetails(Integer userId);
}
编译器在下面的代码中抱怨:
public class TestFunctionalInterface {
public static void main(String[] args) {
User user = a -> a*2;
System.out.println("FetchedData:"+user.fetchData(2));
}
}
在线用户user = a - >一个* 2;
带有消息“此表达式的目标类型必须是有效的 接口”。
答案 0 :(得分:2)
如果其他模块正在使用该接口,则不会发生编译错误,例如,如果该接口通过依赖项可用。有人使用你的模块可以安全地在lambda中使用该函数,而不用担心以后的更新会破坏他们的代码。
答案 1 :(得分:1)
功能界面只能有一个抽象方法。如果您有两种抽象方法,那么您的界面将不再起作用。
如果你有一个抽象方法,你可以使用lambda表达式。
如果你看到@FunctionalInterface注释,你知道你不应该添加任何新方法,因为它会破坏设计。
如果向任何java接口添加新的抽象方法,它将会破坏代码,因为您需要为具体类提供实现
答案 2 :(得分:1)
通过@functionalInterface保护接口的主要优点是使用lambda实例化它们。
Lambda声明只能声明一个代码块,所以如果你的接口没有保护,有些会添加一个抽象方法你的lambda没有更多的意义......
为什么强烈建议不要用lambda实现一些隐式功能接口。
因此,如果您想通过lambda方式实现此接口,我建议您添加一个安全性的注释。如果你不想要这种实现,或者如果你的界面会发生变化或者有改变的风险,那么就不要这样做了
答案 3 :(得分:0)
是的,这个@FunctionalInterface
注解是为了确保开发者在这个接口中只写一个抽象方法,为什么?因为如果再有一个抽象类意味着 lambda 表达式 就失去了它的特性。
正确的例子
@FunctionalInterface
public interface TestFun {
void test();
}
错误代码
@FunctionalInterface
public interface TestFun {
void test();
void m(); // new methods added will lost @FunctionalInterface it's feature
}
让我们使用 TestFun
接口使用 lambda 表达式。
public class App {
public static void main(String[] args) {
TestFun t = () -> {System.out.println("I'm working"); };
}
}
正如我们看到的使用 t = ()->{}
而不告诉我们的代码我们想使用直接使用的 void test()
,这里我们的想法是,如果我们像第二个一样编写两个方法,这样我们就不能使用lambda 表达式在这种情况下我们应该使用 @FunctionalInterface
来限制开发人员只能使用一种抽象方法。
下面的代码是来自 Runnable
接口和 Thread
类的真实示例。
Thread
类:
public class Thread implements Runnable {
*// .......*
}
Runnable
界面:
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}