我遇到了一个问题,在java编译器的1.8.0_05和1.8.0_20 (beta)版本之间,允许的Lambda语法发生了变化。
示例:
package scratch;
import javafx.scene.control.MenuItem;
public class Test
{
public void test()
{
MenuItem mi = new MenuItem();
//This compiles anywhere
mi.setOnAction(e -> System.out.println("hi"));
//as does this
mi.setOnAction(e -> {System.out.println("hi");});
//This doesn't on build 1.8.0_20-ea-b13 - but does on build 1.8.0_05-b13
mi.setOnAction(e -> (System.out.println("hi")));
}
}我想知道的是,最后一个例子是一个有效的Lambda表达式吗?他们刚刚加强了编译器的验证?或者在最新的1.8编译器中有错误吗?
最新编译器打印的错误是:
/scratch/src/scratch/Test.java:18: error: method setOnAction in class MenuItem cannot be applied to given types;
mi.setOnAction(e -> (System.out.println("hi")));
^
required: EventHandler<ActionEvent>
found: (e)->(Syst[...]hi"))
reason: argument mismatch; bad return type in lambda expression
missing return value
1 error编辑(因为我似乎无法在回复中格式化评论):
setOnAction方法的实现是:
public final void setOnAction(EventHandler<ActionEvent> value) {
onActionProperty().set( value);
}和EventHandler:
@FunctionalInterface
public interface EventHandler<T extends Event> extends EventListener {
/**
* Invoked when a specific event of the type for which this handler is
* registered happens.
*
* @param event the event which occurred
*/
void handle(T event);
}发布于 2014-06-10 17:27:41
在Java语言中,方法调用表达式是一个表达式语句,它可以出现在两个位置,需要一个表达式或需要一个语句。
因此,即使方法返回param -> expression,也可以将简化表达式表单e -> System.out.println("hi")用于用例e -> System.out.println("hi")。因为这里所期望的函数签名是<T extends Event> T -> void,所以包含对void方法的单个调用的lambda表达式对于这个上下文是有效的。
当您试图在需要表达式的不同上下文中使用表达式语句时,情况会发生变化。比较JLS§15.1
当调用不返回值的方法(§15.12),即声明为无效的方法(§8.4)时,表达式不表示任何值。这样的表达式只能用作表达式语句(第14.8节),因为表达式出现的每一个其他上下文都需要表达式来表示某事。
正式应用此规则,即使像在(System.out.println("hi"))中那样简单地设置大括号也是无效的,因为这是一个复合表达式,试图在需要“实际表达式”(返回值)的上下文中使用声明为void的方法调用。
因此,使用无效表达式(如mi.setOnAction(e -> (System.out.println("hi")));中的)的lambda表达式也不能有效。这个信息有点误导人。编译器似乎关注的是,表单( whatever )的表达式是非语句表达式,因此在void上下文中不能有效。但是,报告将void方法调用放在圆括号中的初始错误将更有用。
不能将( … )放在void方法调用周围的规则没有改变,因此错误是较老的编译器接受了这个语法,而这个语法现在似乎已经修复了。
https://stackoverflow.com/questions/24146285
复制相似问题