Sta*_*end 2 java functional-programming task consumer
我的问题是在什么情况下或在什么情况下最好使用可调用接口而不是简单的单一方法功能接口。
假设我们有一个带有基于任务的事件处理系统的游戏。它每秒循环一个事件队列。每个事件都涉及一名玩家。在什么情况下最好这样做
Consumer<Player> c1 = (player) -> player.sendMessage("hey");
Run Code Online (Sandbox Code Playgroud)
超过
Runnable r1 = () -> player.sendMessage("hey");
Run Code Online (Sandbox Code Playgroud)
刚刚发现这个问题:Java 中 Runnable 和 Callable 接口之间的区别。它解释了有关多线程环境的一些要点,但我所说明的情况涉及单线程环境。那还有关系吗?
我认为您可能误解了“功能界面”的含义。在 Java 中,“函数式接口”有一个非常具体的含义:interface
只有一个抽象方法。Java 上下文中函数式接口的价值在于它们在 lambda 表达式中的使用。添加了一个注释来表示明确设计为功能性的接口。但它没有任何运行时语义:任何符合标准的接口都是功能性的。
所以,实际上Runnable
是一个具有单一抽象方法的函数式接口run
。这使您的短语“例如使用功能接口而不是可运行的接口”毫无意义。
Java 在java.util.function
包中提供了大量预定义的通用功能接口。这些纯粹是为了实用:让您不必创建多个界面,而这些界面基本上都做相同的事情。
我个人的观点是这些应该谨慎使用。在您的情况下,事件处理系统大概是您系统的关键组件,即使您的事件结果是具有相同签名的接口,让它持有实现Event
接口的对象将使您的意图比持有它ObjLongConsumer<Player>
或类似的东西更清晰.
更新:
在您的评论中,您询问是否有理由使您的Task
界面在所有情况下都通用。不,没有理由。使接口或类通用的唯一原因是它是否将在具有不同类型的多个上下文中使用。在您的情况下,如果任务将始终涉及Player
然后使其成为接口方法签名的具体部分,而不是参数化类型。