Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java8Lambda语法更改_Java_Lambda_Compiler Errors_Java 8 - Fatal编程技术网

Java8Lambda语法更改

Java8Lambda语法更改,java,lambda,compiler-errors,java-8,Java,Lambda,Compiler Errors,Java 8,我遇到了一个问题,Lambda的允许语法在java编译器的1.8.0_05和1.8.0_20(beta版)之间发生了变化 例如: package scratch; import javafx.scene.control.MenuItem; public class Test { public void test() { MenuItem mi = new MenuItem(); //This compiles anywhere

我遇到了一个问题,Lambda的允许语法在java编译器的1.8.0_05和1.8.0_20(beta版)之间发生了变化

例如:

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编译器中是否存在bug

最新编译器打印的错误为:

/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
/scratch/src/scratch/Test.java:18:错误:类MenuItem中的方法setOnAction无法应用于给定类型;
mi.setOnAction(e->(System.out.println(“hi”));
^
必需:EventHandler
发现:(e)->(系统[…]hi”))
原因:参数不匹配;lambda表达式中的返回类型错误
缺少返回值
1错误
编辑(因为我似乎无法格式化回复中的评论):

setOnAction方法的实现是:

public final void setOnAction(EventHandler<ActionEvent> value) {
    onActionProperty().set( value);
}
public final void setOnAction(EventHandler值){
onActionProperty().set(值);
}
和事件处理程序:

@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);
}
@functioninterface
公共接口EventHandler扩展了EventListener{
/**
*当此处理程序所针对的类型的特定事件发生时调用
*这种情况经常发生。
*
*@param event发生的事件
*/
无效句柄(T事件);
}

在Java编程语言中,方法调用表达式是一种结构,它可以出现在需要表达式或需要语句的两个位置

因此,对于用例
e->System.out.println(“hi”),您可以使用简化的表达式形式
param->expression
即使该方法返回
void
。由于此处预期的函数签名是
T->void
,因此包含
void
方法的单个调用的lambda表达式在此上下文中有效

当您尝试在需要表达式的不同上下文中使用表达式语句时,情况会发生变化。比较:

当且仅当一个方法调用(§15.12)调用了一个不返回值的方法,即一个声明无效的方法(§8.4)时,表达式不表示任何内容。此类表达式只能用作表达式语句(§14.8),因为表达式出现的所有其他上下文都要求表达式表示某些内容

正式应用此规则,即使像在
(System.out.println(“hi”)
中那样简单地在其周围加上大括号也是无效的,因为这是一个复合表达式,试图在需要“实表达式”(返回值)的上下文中使用声明的
void
方法的方法调用

因此,使用无效表达式的lambda表达式在
mi.setOnAction(e->(System.out.println(“hi”));
中也不可能是有效的。消息有点误导。编译器似乎关注的是
形式的表达式(无论什么)
,是非语句表达式,因此在
void
上下文中无效。但是,报告将
void
方法调用放在圆括号中的初始错误会更有用


您不能将
(…)
放在
无效
方法调用周围的规则没有改变,因此错误是较旧的编译器接受此语法,现在似乎已经修复。

menuItem.setOnAction()的返回类型是什么
新类路径中的方法?@user2163960,请在问题中添加:MenuItem.setOnAction()的定义,以及它作为参数接收的接口。如果方法重载,请包括所有重载方法。谢谢。您是否知道这是一个预期的更改,或者可能是另一个错误修复的副作用?我认为,这与此相关(请参阅“应始终使用lambda body结构来消除重载解析的歧义”)错误报告的直接链接如下: