假设我在Java 8中有以下功能接口:
interface Action<T, U> {
U execute(T t);
}
在某些情况下,我需要一个没有参数或返回类型的操作 . 所以我写这样的东西:
Action<Void, Void> a = () -> { System.out.println("Do nothing!"); };
但是,它给我编译错误,我需要把它写成
Action<Void, Void> a = (Void v) -> { System.out.println("Do nothing!"); return null;};
这很难看 . 有没有办法摆脱 Void
类型参数?
8 回答
我不认为这是可能的,因为函数定义在您的示例中不匹配 .
您的lambda表达式完全被评估为
而你的宣言看起来像
例如,如果您有以下界面
唯一一种兼容性的函数(虽然实例化)看起来像
并且缺少return语句或参数会给你一个编译器错误 .
因此,如果你声明一个带参数并返回一个的函数,我认为不可能把它转换成上面没有提到的函数 .
在功能界面中添加静态方法
Output
您可以使用一个小帮助函数将
Runnable
转换为Action<Void, Void>
(例如,您可以将其放在Action
中):lambda:
实际上代表了一个接口的实现,如:
这与你定义的完全不同 . 这就是你得到错误的原因 .
既然你不能扩展你的
@FunctionalInterface
,也不能推出一个全新的,那么我认为你没有太多的选择 . 但是,您可以使用Optional<T>
接口来表示缺少某些值(返回类型或方法参数) . 但是,这不会使lambda体更简单 .这是不可能的 . 具有非void返回类型的函数(即使它是
Void
)必须返回一个值 . 但是你可以添加静态方法到Action
,它允许你"create"Action
:这将允许您编写以下内容:
仅供参考哪个功能接口可用于方法引用,方法抛出和/或返回值 .
您可以为该特殊情况创建子接口:
它使用default method来覆盖继承的参数化方法
Void execute(Void)
,将调用委托给更简单的方法void execute()
.结果是它使用起来更简单:
如果没有任何内容,请使用Supplier,但返回一些内容 .
如果需要,请使用Consumer,但不返回任何内容 .
如果它既没有,也可以使用Callable,但可能会抛出(最常见的CS术语中的Thunk) .
如果它既没有也不能扔,请使用Runnable .