Java 8 lambda Void参数
假设我在Java 8中有以下功能接口:Java 8 lambda Void参数,java,lambda,java-8,void,Java,Lambda,Java 8,Void,假设我在Java 8中有以下功能接口: interface Action<T, U> { U execute(T t); } 接口动作{ U执行(T); } 对于某些情况,我需要一个没有参数或返回类型的操作。所以我写 大概是这样的: Action<Void, Void> a = () -> { System.out.println("Do nothing!"); }; 动作a=()->{System.out.println(“什么都不做!”);}; 然
interface Action<T, U> {
U execute(T t);
}
接口动作{
U执行(T);
}
对于某些情况,我需要一个没有参数或返回类型的操作。所以我写
大概是这样的:
Action<Void, Void> a = () -> { System.out.println("Do nothing!"); };
动作a=()->{System.out.println(“什么都不做!”);};
然而,它给了我编译错误,我需要把它写成
Action<Void, Void> a = (Void v) -> { System.out.println("Do nothing!"); return null;};
Action a=(Void v)->{System.out.println(“什么都不做!”);返回null;};
这很难看。有没有办法去掉Void
类型参数?lambda:
() -> { System.out.println("Do nothing!"); };
实际上表示接口的实现,如:
public interface Something {
void action();
}
这和你定义的完全不同。这就是为什么会出现错误
既然你不能扩展你的
@functional界面,也不能引入一个全新的界面,那么我认为你没有太多的选择。但是,您可以使用可选接口来表示缺少某些值(返回类型或方法参数)。但是,这并不会使lambda主体变得更简单。我认为这是不可能的,因为函数定义在您的示例中不匹配
lambda表达式的计算结果与
void action() { }
而你的声明看起来
Void action(Void v) {
//must return Void type.
}
new VoidInterface() {
public Void action(Void v) {
//do something
return v;
}
}
例如,如果您有以下接口
public interface VoidInterface {
public Void action(Void v);
}
package example;
interface Action<T, U> {
U execute(T t);
static Action<Void,Void> invoke(Runnable runnable){
return (v) -> {
runnable.run();
return null;
};
}
}
public class Lambda {
public static void main(String[] args) {
Action<Void, Void> a = Action.invoke(() -> System.out.println("Do nothing!"));
Void t = null;
a.execute(t);
}
}
唯一一种可兼容的函数(实例化时)如下所示
Void action(Void v) {
//must return Void type.
}
new VoidInterface() {
public Void action(Void v) {
//do something
return v;
}
}
缺少返回语句或参数都会导致编译器错误
因此,如果您声明一个函数,它接受一个参数并返回一个参数,我认为不可能将其转换为上述两个函数都不执行的函数。您所追求的语法是可以使用一个小的辅助函数将Runnable
转换为Action
(例如,您可以将其放置在操作中):
公共静态操作(Runnable-Runnable){
返回(v)->{
runnable.run();
返回null;
};
}
//代码中的其他地方
Action Action=Action(()->System.out.println(“foo”);
这是不可能的。具有非无效返回类型的函数(即使它是void
)必须返回一个值。但是,您可以将静态方法添加到操作
,允许您“创建”一个操作
:
interface Action<T, U> {
U execute(T t);
public static Action<Void, Void> create(Runnable r) {
return (t) -> {r.run(); return null;};
}
public static <T, U> Action<T, U> create(Action<T, U> action) {
return action;
}
}
您可以为该特殊情况创建子接口:
interface Command extends Action<Void, Void> {
default Void execute(Void v) {
execute();
return null;
}
void execute();
}
在函数接口中添加静态方法
public interface VoidInterface {
public Void action(Void v);
}
package example;
interface Action<T, U> {
U execute(T t);
static Action<Void,Void> invoke(Runnable runnable){
return (v) -> {
runnable.run();
return null;
};
}
}
public class Lambda {
public static void main(String[] args) {
Action<Void, Void> a = Action.invoke(() -> System.out.println("Do nothing!"));
Void t = null;
a.execute(t);
}
}
仅供参考,在方法抛出和/或返回值的情况下,哪个函数接口可用于方法引用
void notReturnsNotThrows() {};
void notReturnsThrows() throws Exception {}
String returnsNotThrows() { return ""; }
String returnsThrows() throws Exception { return ""; }
{
Runnable r1 = this::notReturnsNotThrows; //ok
Runnable r2 = this::notReturnsThrows; //error
Runnable r3 = this::returnsNotThrows; //ok
Runnable r4 = this::returnsThrows; //error
Callable c1 = this::notReturnsNotThrows; //error
Callable c2 = this::notReturnsThrows; //error
Callable c3 = this::returnsNotThrows; //ok
Callable c4 = this::returnsThrows; //ok
}
interface VoidCallableExtendsCallable extends Callable<Void> {
@Override
Void call() throws Exception;
}
interface VoidCallable {
void call() throws Exception;
}
{
VoidCallableExtendsCallable vcec1 = this::notReturnsNotThrows; //error
VoidCallableExtendsCallable vcec2 = this::notReturnsThrows; //error
VoidCallableExtendsCallable vcec3 = this::returnsNotThrows; //error
VoidCallableExtendsCallable vcec4 = this::returnsThrows; //error
VoidCallable vc1 = this::notReturnsNotThrows; //ok
VoidCallable vc2 = this::notReturnsThrows; //ok
VoidCallable vc3 = this::returnsNotThrows; //ok
VoidCallable vc4 = this::returnsThrows; //ok
}
void notReturnsNotThrows(){};
void notReturnsThrows()引发异常{}
字符串returnsNotThrows(){return”“;}
字符串returnsThrows()引发异常{return”“;}
{
Runnable r1=this::notReturnsNotThrows;//确定
Runnable r2=this::notReturnsThrows;//错误
Runnable r3=this::returnsNotThrows;//确定
Runnable r4=this::returnsThrows;//错误
Callable c1=this::notReturnsNotThrows;//错误
Callable c2=this::notReturnsThrows;//错误
Callable c3=this::returnsNotThrows;//确定
Callable c4=this::returnsThrows;//确定
}
接口voidCallableExtendCallable扩展Callable{
@凌驾
Void call()抛出异常;
}
接口可调用{
void call()抛出异常;
}
{
voidCallableExtendCallable vcec1=this::notReturnsNotThrows;//错误
voidCallableExtendCallable vcec2=this::notReturnsThrows;//错误
voidCallableExtendCallable vcec3=this::returnsNotThrows;//错误
voidCallableExtendCallable vcec4=this::returnsThrows;//错误
VoidCallable vc1=this::notReturnsNotThrows;//确定
VoidCallable vc2=this::notReturnsThrows;//确定
VoidCallable vc3=this::returnsNotThrows;//确定
VoidCallable vc4=this::returnsThrows;//确定
}
如果不需要任何东西,但返回一些东西,请使用
如果它需要一些东西,但不返回任何东西,则使用
如果它返回一个结果并可能抛出,则使用(最类似于一般的CS术语)
如果两者都不能抛出,请使用。我认为这张表很短,很有用:
Supplier () -> x
Consumer x -> ()
Callable () -> x throws ex
Runnable () -> ()
Function x -> y
BiFunction x,y -> z
Predicate x -> boolean
UnaryOperator x1 -> x2
BinaryOperator x1,x2 -> x3
正如在其他答案中所说,这个问题的合适选项是Runnable
看看如果您需要一个操作,正如您定义的那样,这是不可能的。但是,您的第一个示例可以放入Runnable
,这就是您正在寻找的Runnable r=()->System.out.println(“什么都不做!”);
@BobTheBuilder我不想像那篇文章中建议的那样使用使用者。马特的回答使类型可以工作,但是调用者在得到空返回值时会做什么?你可以交叉手指,希望Java 9接受中的建议2和3!问题是你的Something
函数不能是我的的子类型>Action
type,我不能有两种不同的类型。技术上他可以,但他说他想避免:)这是你能得到的最干净的解决方法,依我看,so+1(或使用界面本身的静态方法)Konstantin Yovkov下面的解决方案(带有@FunctionInterface)是一个更好的解决方案,因为它不涉及泛型,也不需要额外的代码。@uthomas抱歉,我没有看到涉及@functionanterface
的答案。他只是说,不可能扩展它…嗨,马特,对不起。我反应太快了。对于给定的问题,你的答案是完全正确的。不幸的是,我的投票被锁定了,所以我不能删除我对这个答案的-1。注二:1。除了Runnable
操作之外,还应该使用一个自定义的@functional接口
一种称为副作用的东西
,2。对这样的帮助函数的需要突出显示出一些奇怪的事情正在发生,可能抽象被破坏了。例如,我这样做是为了包装“void”返回调用:公共静态void wrapCall(Runnable r){r.run();}
。谢谢你漂亮的回答。简短而精确。不幸的是,如果它必须抛出已检查的异常,则没有帮助。如