Java 8 lambda无效参数
假设我在Java 8中有以下function接口:
interface Action<T, U> { U execute(T t); } 对于某些情况,我需要一个没有参数或返回types的动作。 所以我写这样的东西:
 Action<Void, Void> a = () -> { System.out.println("Do nothing!"); }; 
不过,它给我编译错误,我需要把它写成
 Action<Void, Void> a = (Void v) -> { System.out.println("Do nothing!"); return null;}; 
 这是丑陋的。 有没有什么办法摆脱Voidtypes的参数? 
 你所追求的语法可以通过一个辅助函数来实现,这个辅助函数可以将一个Runnable转换成Action<Void, Void> (你可以把它放在Action中): 
 public static Action<Void, Void> action(Runnable runnable) { return (v) -> { runnable.run(); return null; }; } // Somewhere else in your code Action<Void, Void> action = action(() -> System.out.println("foo")); 
 使用Supplier如果它不需要。 
 使用Consumer如果它没有返回 
 如果两者都不使用,则使用Runnable 。 
拉姆达:
 () -> { System.out.println("Do nothing!"); }; 
实际上代表一个接口的实现,如:
 public interface Something { void action(); } 
这与你所定义的完全不同。 这就是为什么你得到一个错误。
 既然你不能扩展你的@FunctionalInterface ,也不能引入一个全新的,那么我认为你没有太多select。 但是,可以使用Optional<T>接口来表示某些值(返回types或方法参数)缺失。 但是,这不会使拉姆达体更简单。 
您可以为该特殊情况创build一个子接口:
 interface Command extends Action<Void, Void> { default Void execute(Void v) { execute(); return null; } void execute(); } 
 它使用默认方法来覆盖inheritance的参数化方法Void execute(Void) ,将调用委托给更简单的方法void execute() 。 
结果是使用起来简单多了:
 Command c = () -> System.out.println("Do nothing!"); 
 这是不可能的。 具有非void返回types的函数(即使它是Void )必须返回一个值。 但是,您可以将Action方法添加到Action ,以便“创build”一个Action : 
 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; } } 
这将允许你写下面的内容:
 // create action from Runnable Action.create(()-> System.out.println("Hello World")).execute(null); // create normal action System.out.println(Action.create((Integer i) -> "number: " + i).execute(100)); 
我不认为这是可能的,因为在你的例子中函数定义不匹配。
你的lambdaexpression式完全按照
 void action() { } 
而你的声明看起来像
 Void action(Void v) { //must return Void type. } 
作为一个例子,如果你有以下接口
 public interface VoidInterface { public Void action(Void v); } 
唯一types的function(虽然实例化)将是兼容性看起来像
 new VoidInterface() { public Void action(Void v) { //do something return v; } } 
并且缺乏返回语句或参数会给你一个编译器错误。
因此,如果你声明了一个带参数的函数并返回一个函数,我认为不可能把它转换成上面没有提到的函数。
在你的function界面中添加一个静态方法
 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); } } 
产量
 Do nothing! 
只是为了引用哪个函数接口可以用于方法引用的情况下方法抛出和/或返回一个值。
 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 }